CSP送货问题C语言版---For初学者

本文用纯C语言来编写,适合初学者,编译环境是Code::Blocks。
问题描述
为了增加公司收入,F 公司新开设了物流业务。由于 F 公司在业界的
良好口碑,物流业务一开通即受到了消费者的欢迎,物流业务马上遍及了
城市的每条街道。然而,F 公司现在只安排了小明一个人负责所有街道的
服务。
任务虽然繁重,但是小明有足够的信心,他拿到了城市的地图,准备
研究最好的方案。城市中有 n 个交叉路口,m 条街道连接在这些交叉路口
之间,每条街道的首尾都正好连接着一个交叉路口。除开街道的首尾端点,
街道不会在其他位置与其他街道相交。每个交叉路口都至少连接着一条街
道,有的交叉路口可能只连接着一条或两条街道。
小明希望设计一个方案,从编号为 1 的交叉路口出发,每次必须沿街
道去往街道另一端的路口,再从新的路口出发去往下一个路口,直到所有
的街道都经过了正好一次。
输入格式
输入的第一行包含两个整数 n, m,表示交叉路口的数量和街道的数量,
交叉路口从 1 到 n 标号。
接下来 m 行,每行两个整数 a, b,表示和标号为 a 的交叉路口和标号
为 b 的交叉路口之间有一条街道,街道是双向的,小明可以从任意一端走
向另一端。两个路口之间最多有一条街道。
输出格式
如果小明可以经过每条街道正好一次,则输出一行包含 m+1 个整数 p1,
p2, p3, …, pm+1,表示小明经过的路口的顺序,相邻两个整数之间用一个
空格分隔。如果有多种方案满足条件,则输出字典序最小的一种方案,即
首先保证 p1最小,p1最小的前提下再保证 p2最小,依此类推。
如果不存在方案使得小明经过每条街道正好一次,则输出一个整数-1。
样例输入
4 5
1 2
1 3
1 4
2 4
3 4
样例输出
1 2 4 1 3 4
在这里插入图片描述
主要考察欧拉路,首先判断能不能形成欧拉路或者欧拉回路,至于什么是欧拉路可以看离散数学or百度,排除完,剩下的就是能形成欧拉路的情况,首先用邻接链表存储图的结构(当然也可以用邻接矩阵。),对链表进行排序或者有序插入均可,因为题目中要输出字典序最小的,最重要的就是输出,靠一个visited_edge的二维矩阵来保证边只被遍历一次(相当于做标记,就好比DFS对节点标记一样。)这是大概地思路。
本人能力有限,难免出错,欢迎大神评论指点,再有,这个代码仅供参考,希望参考者能写出更棒的、更高效的代码,ps:代码还未简化,略糙。
代码如下:

#include<stdio.h>
#include <stdlib.h>
#include<string.h>

typedef struct Node
{
   
   int adj_v;
  struct Node *next;
}EdgeNode;
typedef struct
{
   
    int vert;
    int size;
    EdgeNode *first_edge;
}VertNode;
typedef struct
{
   
    VertNode *adjlink;
    int **visited_edge;
     int *visited;
    int vert_num,edge_num;
}AdjLGraph;

int InsertEdge(AdjLGraph *,int,int);
void InitGraph(AdjLGraph **,int,int);
int DFS(AdjLGraph *);
int Euler(AdjLGraph *);
void PrintPath(AdjLGraph *);
void SortGraph(AdjLGraph *);
void SortAdjLink(EdgeNode *);
int NotDone(AdjLGraph *);
int main()
{
   
    int v,e,v1 = -1,v2 = -1,i;
    scanf("%d%d",&v,&e);
    AdjLGraph *G;
    G = malloc(sizeof(AdjLGraph));
    InitGraph(&G,v,e);
    for(i =0;i < e;i++)
    {
   
        scanf("%d%d",&v1,&v2);
        if(!InsertEdge(G,v1,v2))
            break;
    }
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值