题目意思:求递增的最短路
思路,先对所有边进行排序,逐层进行算最短路
代码:
View Code
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 #define M 50001 7 #define N 10001 8 __int64 inf = 10000000000000000LL; 9 struct st 10 { 11 int u,v,w; 12 }p[M]; 13 __int64 d[N],dd[M * 5],flag[N],vv[M * 5]; 14 int n,m; 15 bool fan(struct st A,struct st B) 16 { 17 if(A.w < B.w) 18 return true; 19 return false; 20 } 21 void solve(int st,int en) 22 { 23 int cnt = 0; 24 for(int i = st;i < en;i ++) 25 { 26 int r = p[i].u,l = p[i].v,dis = p[i].w; 27 if(flag[r] && d[l] > d[r] + dis) 28 { 29 dd[cnt] = d[r] + dis; 30 vv[cnt] = l; 31 cnt ++; 32 } 33 if(flag[l] && d[r] > d[l] + dis) 34 { 35 dd[cnt] = d[l] + dis; 36 vv[cnt] = r; 37 cnt ++; 38 } 39 } 40 for(int i = 0;i < cnt;i ++) 41 { 42 d[vv[i]] = min(d[vv[i]],dd[i]); 43 flag[vv[i]] = 1; 44 } 45 } 46 int main() 47 { 48 int t; 49 scanf("%d",&t); 50 while(t --) 51 { 52 memset(flag,0,sizeof(flag)); 53 scanf("%d %d",&n,&m); 54 for(int i = 1;i <= n;i ++) d[i] = inf; 55 d[1] = 0; 56 flag[1] = 1; 57 for(int i = 1;i <= m;i ++) 58 scanf("%d %d %d",&p[i].u,&p[i].v,&p[i].w); 59 sort(p + 1,p + m + 1,fan); 60 int i,j; 61 for(i = 1;i <= m;i ++) 62 { 63 for(j = i + 1;j <= m;j ++) 64 if(p[i].w != p[j].w) 65 break; 66 solve(i,j); 67 i = j - 1; 68 } 69 if(d[n] == inf) 70 printf("No answer\n"); 71 else 72 printf("%I64d\n",d[n]); 73 74 } 75 return 0; 76 }