圣诞岛的旅行

本文介绍了一个寻找从起点到终点最快及最慢路径的算法。通过构建单向图并使用递归方式遍历所有可达节点来确定最短和最长路径所需时间。同时提供了完整的源代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem
Angel最近无聊,去了圣诞岛(CX *^_^*),他喜欢无目的的乱逛,当然,他不会轻易地回头。Angel想去广场,那么,他什么时候才能到呢?你已经得到了CX的地图,地图上有N(N <= 100)个交叉路口,交叉路口之间有马路相连接(不超过1000条马路)。因为CX的人遵循奇怪的规则,道路都是单向的,不同的道路之间有一定的距离,我们假设Angel所在的地点为点1,广场所在点为N。假设Angel走一单位距离需要一单位时间。问Angel最早和最迟什么时候到达广场?

Input
本题有多组数据,第一行N, M,M是边的数量以后M行,每行3个整数X, Y, Weight,代表一条从X城市到Y城市,长度为Wweight的边。

Output
每组数据,第一行是最少时间,第二行是最迟时间,要是可怜的Angel可能永远到不了广场,输出一行Never。

Sample Input
5 5
1 2 1
1 4 10
2 3 1
3 4 1
4 5 1

Sample Output
4
11

源码:

#include<stdio.h>
#include<assert.h>
#ifdef_DEBUG
#include<stack>//forshowingpath
#endif
#defineMAX_N100
#defineMAX_M1000
#defineCOST_IFINITE-1
intn,m;
struct_List
{
intvertex;
intcost;
_List*next;
};
structVertex_t
{
Vertex_t():cost(COST_IFINITE),parent(0),isVisited(false),head(NULL),worstCost(COST_IFINITE)
{/**/}
_List*head;
intcost;
intparent;
boolisVisited;

intworstParent;
intworstCost;
};
Vertex_tvertics[MAX_N+1];
intmin_cost,max_cost;
Vertex_t*min_who,*max_who;
voidReadGraph(FILE*file)
{
inti=m;
while(i-->0)
{
inta,b,c;
fscanf(file,"%d%d%d/n",&a,&b,&c);
_List*p=new_List;
p->vertex=b;
p->cost=c;
p->next=NULL;
if(vertics[a].head==NULL)
{
vertics[a].head=new_List;
vertics[a].head->vertex=a;
vertics[a].head->next=p;
}else
{
p->next=vertics[a].head->next;
vertics[a].head->next=p;
}
}
}
voidResolve(inttoVisit,intcost,Vertex_t*who)
{
if(toVisit<1||toVisit>n)
return;
if(!vertics[toVisit].isVisited)
{
vertics[toVisit].isVisited=true;
vertics[toVisit].cost=who->cost+cost;
vertics[toVisit].parent=who->head->vertex;

vertics[toVisit].worstCost=who->worstCost+cost;
vertics[toVisit].worstParent=who->head->vertex;
}else
{
if(vertics[toVisit].cost>who->cost+cost)
{
vertics[toVisit].cost=who->cost+cost;
vertics[toVisit].parent=who->head->vertex;
}
if(vertics[toVisit].worstCost<who->worstCost+cost)
{
vertics[toVisit].worstCost=who->worstCost+cost;
vertics[toVisit].worstParent=who->head->vertex;
}else
return;
}
if(toVisit==n)
{
if(!min_who||cost+who->cost<min_cost)
{
min_cost=cost+who->cost;
min_who=who;
}
if(!max_who||who->worstCost+cost>max_cost)
{
max_who=who;
max_cost=who->worstCost+cost;
}
return;
}
_List*p=vertics[toVisit].head->next;
while(p)
{
Resolve(p->vertex,p->cost,&vertics[toVisit]);
p=p->next;
}
}
intmain()
{
vertics[1].cost=0;
vertics[1].worstCost=0;
FILE*fp=fopen("data.dat","rb");
fscanf(fp,"%d%d/n",&n,&m);
ReadGraph(fp);
_List*p=vertics[1].head->next;
while(p)
{
Resolve(p->vertex,p->cost,&vertics[1]);
p=p->next;
}
if(min_who==NULL)
{
printf("Impossible!/n");
return0;
}
printf("min%d/n",min_cost);
if(max_who==NULL)
{
printf("Impossible!/n");
return0;
}
printf("max%d/n",max_cost);

#ifdef_DEBUG
{
Vertex_t*pv=min_who;
usingstd::stack;
stack<int>path;
path.push(n);
while(pv->parent)
{
path.push(pv->head->vertex);
pv=&vertics[pv->parent];
}
path.push(1);
while(path.size()!=0)
{
printf("%d",path.top());
path.pop();
}
printf("/n");
}
{
Vertex_t*pv=max_who;
usingstd::stack;
stack<int>path;
path.push(n);
while(pv->worstParent)
{
path.push(pv->head->vertex);
pv=&vertics[pv->worstParent];
}
path.push(1);
while(path.size()!=0)
{
printf("%d",path.top());
path.pop();
}
printf("/n");
}
#endif//_DEBUG
return0;
}
//data.dat
55
1220
1410
231
3420
451
//output
min11
max42
145
12345
Pressanykeytocontinue

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值