Hdu - 2544 - 最短路
上题目:
最短路
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 21107 Accepted Submission(s): 8998
Problem Description
在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?
Input
输
入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店
所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B&
lt;=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。
输入保证至少存在1条商店到赛场的路线。
输入保证至少存在1条商店到赛场的路线。
Output
对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间
Sample Input
2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0
Sample Output
3 2
这一题难度其实不大,要注意dij只可以用在DAG上面,这一题有环,不可以用dij,当然,我看到别人好像用dij过了,目测是我的dij有什么问题= =。
这里我用了flyod,当然还有其他更好地办法,毕竟flyod复杂度在O(n^3)。不过flyod写起来比较简单= =。
最近精神有点xx,写个dij也写错了2次= =,结果交上去了还是wa,最后才换成flyod就过了,可是时间好像慢了点,用了45MS。= =。看来还要继续努力啊。
上代码:
1 int s[MAX][MAX],dis[MAX]; 2 3 4 void dij(int n) 5 { 6 int i,j,flag,minn; 7 bool fin[MAX]; 8 for(i=2;i<=n;i++) dis[i]=s[1][i] ? s[1][i] : INF; 9 memset(fin,0,sizeof(fin)); 10 fin[1]=1; 11 i=1; 12 for(j=2;j<=n;j++) 13 { 14 minn=INF; 15 for(i=1;i<=n;i++) if(!fin[i] && dis[i]<minn) {minn=dis[i];flag=i;} 16 fin[flag]=1; 17 for(j=1;j<=n;j++) 18 { 19 if(!fin[j] && s[flag][j] && (minn+s[flag][j]<dis[j])) 20 dis[j]=minn+s[flag][j]; 21 } 22 } 23 }
1 #include <stdio.h> 2 #include <string.h> 3 #define MAX 100+10 4 #define INF 1000000000 5 using namespace std; 6 7 int s[MAX][MAX],d[MAX][MAX]; 8 9 10 void flyod(int n) 11 { 12 int i,j,u; 13 memcpy(d,s,sizeof(s)); 14 for(i=1;i<=n;i++) 15 for(j=1;j<=n;j++) 16 if(!d[i][j]) d[i][j] = i==j ? 0 : INF; 17 18 for(u=1;u<=n;u++) 19 { 20 for(i=1;i<=n;i++) 21 { 22 for(j=1;j<=n;j++) 23 { 24 d[i][j] = (d[i][j] > d[i][u]+d[u][j]) ? (d[i][u]+d[u][j]) : d[i][j]; 25 } 26 } 27 } 28 } 29 30 int main() 31 { 32 int n,m,i,x,y,di,e; 33 while(scanf("%d %d",&n,&m),(n && m)) 34 { 35 memset(s,0,sizeof(s)); 36 for(i=1;i<=m;i++) 37 { 38 scanf("%d %d %d",&x,&y,&di); 39 s[x][y]=di; 40 s[y][x]=di; 41 } 42 flyod(n); 43 e=d[1][n]; 44 printf("%d\n",e); 45 } 46 return 0; 47 }
补充一个用spfa过的代码
1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #define MAX 100000+10 5 #define INF 1000000000 6 using namespace std; 7 8 typedef struct 9 { 10 int v; 11 int l; 12 int next; 13 }path; 14 15 path p[MAX]; 16 int head[MAX],dis[MAX],c[MAX],n,m,tot; 17 bool vin[MAX]; 18 queue<int> q; 19 20 void add(int u,int v,int l) 21 { 22 p[tot].v=v; 23 p[tot].l=l; 24 p[tot].next=head[u]; 25 head[u]=tot++; 26 } 27 28 bool spfa(int s) 29 { 30 int i,u,v; 31 for(i=1;i<=n;i++) {dis[i]=INF;} 32 dis[s]=0; 33 while(!q.empty()) q.pop(); 34 memset(vin,0,sizeof(vin)); 35 memset(c,0,sizeof(c)); 36 q.push(s); 37 vin[s]=1; 38 c[s]++; 39 while(!q.empty()) 40 { 41 u=q.front(); 42 q.pop(); 43 vin[u]=0; 44 for(v=head[u];v!=-1;v=p[v].next) 45 { 46 if(dis[p[v].v] > dis[u]+p[v].l) 47 { 48 dis[p[v].v]=dis[u]+p[v].l; 49 if(!vin[p[v].v]) 50 { 51 q.push(p[v].v); 52 c[v]++; 53 vin[p[v].v]=1; 54 if(c[p[v].v]>n) return 0; 55 } 56 } 57 } 58 } 59 return 1; 60 } 61 62 int main() 63 { 64 int i,u,v,l; 65 //freopen("data.txt","r",stdin); 66 while(scanf("%d %d",&n,&m),(n && m)) 67 { 68 memset(p,0,sizeof(p)); 69 memset(head,-1,sizeof(head)); 70 tot=0; 71 for(i=0;i<m;i++) 72 { 73 scanf("%d %d %d",&u,&v,&l); 74 add(u,v,l); 75 add(v,u,l); 76 } 77 spfa(1); 78 printf("%d\n",dis[n]); 79 } 80 return 0; 81 }