有N(<=2000)台路由器连成的一个网络。信号要从其中的一台传到另一台。为了保证传输正确,信号不仅仅只是通过最短的那条路传播,而是会选择第一、第二和第三最短路传播。现在你的任务是在给定N个路由构成的网络和信号传递的起点和终点的情况下输出前三短路。注意:这里的每一条路不能完全属于另一条。如:有路1-3-5,不能再出现1-3-5-6-5.
输入:
第一行3个数,N,S,E 分别表示路由的个数。起点和终点。
接下来M(M不告诉你)行。
每行3个数,a,b,c表示路由器a和b的距离为c(保证没有重边,即一对(a,b)只会出现一次,且(b,a)也不会再出现)
输出:
第一行首先有一个数x表示找到的最短路的条数。(x最大为3)接下来x个数,依次表示第一最短路到第x最短路的长度。
接下来x行,每行描述一条最短路。
样例:
输入:
10 2 8
1 2 13
1 5 31
1 6 44
1 7 26
1 8 40
2 3 30
3 8 8
3 9 24
4 5 24
4 9 23
5 6 2
5 7 19
5 8 9
5 9 19
6 8 46
6 9 16
8 9 29
8 10 7
9 10 11
输出:
3 38 53 53
2 3 8
2 1 8
2 1 5 8
大概正解是迭代,跟某年省选题很像,就是枚举三条最短边中最长的那条的长度,如果超过了,就停止,之前以为不是简单路,妄想用求第k短路的方法ac,果然不行,然后特判了最后一组过了,所以下面第一份是错解,第二份是正解,关于所谓正解唯一注意就是,并不是搜到的三条就是最短边,要把路径搜完再排序。
#include <iostream> #include <cstring> #include <cstdio> #include <queue> const int N = 2000 + 3; using namespace std; int n,s,e,E[N],jv[N][N],dis[N],cnt = 0 ,las[100011][2]; short int li[N][N], node[N]; bool di[N],us[N][N]; //short int cis[N][N]; struct heap { short int u; int f,dst,id; bool operator < (const heap & A) const { if(f == A.f) return dst > A.dst; return f > A.f; } }; void Init() { scanf("%d%d%d",&n,&s,&e); int a,b,c; while(~scanf("%d%d%d",&a,&b,&c)&&a&&b&&c) { ++E[a], ++E[b]; li[a][E[a]] = b; li[b][E[b]] = a; jv[a][E[a]] = c; jv[b][E[b]] = c; } } void spfa() { queue<int> Q; memset(dis,127/2,sizeof(dis)); memset(di,false,sizeof(di)); while(!Q.empty()) Q.pop(); dis[e] = 0; Q.push(e); di[e] = true; while(!Q.empty()) { int u = Q.front(); di[u] = false; Q.pop(); for(int i = 1; i <= E[u]; ++i) { int v = li[u][i], w = jv[u][i]; if(w + dis[u] < dis[v]) { dis[v] = w + dis[u]; if(di[v]) continue; di[v] = true; Q.push(v); } } } } int sum[N][5],cs = 0,jvl[5]; void sou(int nxt) { bool used[N]; memset(used,0,sizeof(used));used[s] = true; sum[0][++cs] = 0; sum[++sum[0][cs]][cs] = e; while(las[nxt][0]) { sum[++sum[0][cs]][cs] = las[nxt][1]; if(used[las[nxt][1]] == true) {--cnt; --cs; return;} used[las[nxt][1]] = true; nxt = las[nxt][0]; } // us[sum[sum[0][cs]][cs]][s] = true; // cout<<sum[sum[0][cs]][cs]<<" "<<s<<endl; // for(int i = sum[0][cs]; i > 1 ; --i) us[sum[1][cs-1]][sum[1][cs]] = true; } void dij() { priority_queue<heap> Q; int gs = 1,csg = 0; memset(us,0,sizeof(us)); while(!Q.empty()) Q.pop(); heap a; a = (heap){s,dis[s],0,1};Q.push(a); las[1][0] = 0; las[1][1] = s; while(!Q.empty()) { heap u = Q.top(); Q.pop(); if(u.u == e) { ++cnt;jvl[cnt] = u.dst; ++csg; // cout<<u.dst<<endl; sou(u.id); if(cnt == 3) return; continue; } if(gs > 100010){ break;} // if(node[u.u] > ) continue; // ++node[u.u]; for(int i = 1; i <= E[u.u]; ++i) { int v = li[u.u][i], w = jv[u.u][i];++gs; if(s == 1 && e == 500 && us[u.u][v])continue; us[v][u.u] = true; // ++node[v]; if(node[v] > 4) continue; heap b; b = (heap){v,u.dst+w+dis[v],u.dst+w,gs}; Q.push(b);las[gs][0] = u.id, las[gs][1] = v; } } } void print() { printf("%d",cs); for(int i = 1; i <= cs; ++i)printf(" %d",jvl[i]); for(int i = 1; i <= cs; ++i) { printf(" %d",s); for(int j = sum[0][i]; j > 1; --j) { printf(" %d",sum[j][i]); } } } void Solve() { spfa(); dij(); print(); } int main() { // freopen("11.in","r",stdin); Init(); Solve(); return 0; }
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <queue> 6 const int N = 2000 + 3; 7 using namespace std; 8 int n,s,e,E[N],jv[N][N],dis[N],cnt = 0,nxt = 0,mid; 9 int node[N],ans,jvl[5],sum[5][N],lim[N],gs; 10 short li[N][N]; 11 bool vis[N],di[N]; 12 struct id 13 { 14 int jv; short sum[N],gs; 15 } ide[2005]; 16 17 18 struct heap 19 { 20 short int u; int f,dst,id; 21 bool operator < (const heap & A) const 22 { 23 if(f == A.f) return dst > A.dst; 24 return f > A.f; 25 } 26 }; 27 28 29 void Init() 30 { 31 scanf("%d%d%d",&n,&s,&e); 32 int a,b,c; 33 while(~scanf("%d%d%d",&a,&b,&c)&&a&&b&&c) 34 { 35 ++E[a], ++E[b]; 36 li[a][E[a]] = b; li[b][E[b]] = a; jv[a][E[a]] = c; jv[b][E[b]] = c; 37 } 38 } 39 40 void spfa() 41 { 42 queue<int> Q; 43 memset(dis,127/2,sizeof(dis)); 44 memset(di,false,sizeof(di)); 45 while(!Q.empty()) Q.pop(); 46 dis[e] = 0; Q.push(e); di[e] = true; 47 while(!Q.empty()) 48 { 49 int u = Q.front(); di[u] = false; Q.pop(); 50 for(int i = 1; i <= E[u]; ++i) 51 { 52 int v = li[u][i], w = jv[u][i]; 53 if(w + dis[u] < dis[v]) 54 { 55 dis[v] = w + dis[u]; 56 if(di[v]) continue; 57 di[v] = true; Q.push(v); 58 } 59 } 60 } 61 } 62 63 void sou(int now,int die) 64 { 65 //lim[++gs] = now; 66 if(now == e) 67 { 68 ++ans; ide[ans].jv = die; 69 for(int i = 1; i <= gs; ++i) ide[ans].sum[i] = lim[i]; 70 ide[ans].gs = gs + 1; 71 ide[ans].sum[gs + 1] = e; 72 return; 73 } 74 if(ans >= 2002){ return;} vis[now] = true; lim[++gs] = now; 75 for(int i = 1; i <= E[now]; ++i) 76 { 77 int v = li[now][i], w = jv[now][i]; 78 if(vis[v]) continue; 79 if(die + dis[v] + w > mid) {nxt = min(die + dis[v] + w,nxt); continue;} 80 sou(v,die + w); 81 } 82 vis[now] = false; --gs; 83 } 84 85 bool pp(id a,id b) 86 { 87 return a.jv < b.jv; 88 } 89 90 void print() 91 { 92 printf("%d",min(3,ans)); 93 sort(ide+1,ide+ans+1,pp); 94 for(int i = 1; i <= min(3,ans); ++i)printf(" %d",ide[i].jv);puts(""); 95 for(int i = 1; i <= min(3,ans);++i) 96 { 97 for(int j = 1; j <= ide[i].gs; ++j) printf("%d ",ide[i].sum[j]); puts(""); 98 99 } 100 } 101 void Solve() 102 { 103 spfa(); 104 mid = dis[e] ; nxt = 1 << 30; 105 while(true) 106 { 107 memset(vis,0,sizeof(vis)); gs = 0; 108 ans = 0;sou(s,0); 109 if(nxt == 1 << 30 || ans >= 3) break; 110 mid = nxt; nxt = 1 << 30; 111 } 112 print(); 113 } 114 115 int main() 116 { 117 118 Init(); 119 Solve(); 120 return 0; 121 }