HDU--杭电--3790--最短路径问题

 

最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9418    Accepted Submission(s): 2874


Problem Description
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
 

 

Input
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
 

 

Output
输出 一行有两个数, 最短距离及其花费。
 

 

Sample Input
3 2 1 2 5 6 2 3 4 5 1 3 0 0
 

 

Sample Output
9 11

 

 


 

这是用的SPFA算法做的最短路

#include <iostream> #include <cstdio> #include <cstring> #include <queue> #define Max 0xfffffff using namespace std; int n,m,d[1111],p[1111];//d是路程,p是消费 bool qwe[1111];//记录是否在队列中 struct ssss { int x,y; }s[1111][1111];//地图 queue<int> q,qq; void SPFA() { int a,i; while(!q.empty())//只要队列非空 { a=q.front();//取出对首元素 q.pop();//对首出队 qwe[a]=true;//标记在队列外 for(i=1;i<=n;i++)//遍历所有可以到的点 if(i!=a) { if(d[i]>d[a]+s[a][i].x)//满足松弛条件就进行松弛操作 { d[i]=d[a]+s[a][i].x; p[i]=p[a]+s[a][i].y; if(qwe[i])//并判断是否在队外,在队外就入队并标记 { q.push(i); qwe[i]=false; } }else if(d[i]==d[a]+s[a][i].x&&p[i]>p[a]+s[a][i].y) p[i]=p[a]+s[a][i].y; } } } int main (void) { int i,j,a,b,c,e; while(~scanf("%d%d",&n,&m)&&(n||m)) { q=qq; for(i=1;i<=n;i++) { qwe[i]=true; d[i]=p[i]=Max; for(j=1;j<=i;j++) s[i][j].x=s[i][j].y=s[j][i].x=s[j][i].y=Max; } for(i=0;i<m;i++) { scanf("%d%d%d%d",&a,&b,&c,&e); if(s[a][b].x>c)//记录最优条件 { s[a][b].x=s[b][a].x=c; s[a][b].y=s[b][a].y=e; } } scanf("%d%d",&a,&b); d[a]=p[a]=0; qwe[a]=false; q.push(a); SPFA(); printf("%d %d\n",d[b],p[b]); } return 0; }
 这是我刚学SPFA算法做的题,先前只知道dijkstra,而且还是学长说着玩说给我听的,现在学最短路了,就选了这个比较好的算法,最短路问题主要是松弛操作 

 

 

 

你可能感兴趣的:(最短路径)