Connections between cities |
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) |
Total Submission(s): 444 Accepted Submission(s): 142 |
|
Problem Description
After World War X, a lot of cities have been seriously damaged,
and we need to rebuild those cities. However, some materials needed can
only be produced in certain places. So we need to transport these
materials from city to city. For most of roads had been totally
destroyed during the war, there might be no path between two cities, no
circle exists as well.
Now, your task comes. After giving you the condition of the roads, we want to know if there exists a path between any two cities. If the answer is yes, output the shortest path between them. |
Input
Input consists of multiple problem instances.For each instance,
first line contains three integers n, m and c, 2<=n<=10000,
0<=m<10000, 1<=c<=1000000. n represents the number of cities
numbered from 1 to n. Following m lines, each line has three integers
i, j and k, represent a road between city i and city j, with length k.
Last c lines, two integers i, j each line, indicates a query of city i
and city j.
|
Output
For each problem instance, one line for each query. If no path between two cities, output “Not connected”, otherwise output the length of the shortest path between them. |
Sample Input
5 3 2 1 3 2 2 4 3 5 2 3 1 4 4 5 |
Sample Output
Not connected 6 Hint
Hint Huge input, scanf recommended. |
思路:Tarjan求LCA,虚拟一个0号的根节点,如果两个点的lca是0,那么就不连通,否则,任意两点的距离就是:d(u,v)=dist[v]+dist[u]-2*dist[LCA(u,v)];
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <algorithm> 5 #include <cstring> 6 #include <string> 7 #include <cstdlib> 8 using namespace std; 9 10 const int maxn=10100,maxm=30010,maxq=2000010; 11 int cnt,n,x,y,m,z,node,v; 12 bool flag[maxn],vis[maxn]; 13 int h[maxn],h1[maxn],f[maxn],ans[maxn],dis[maxn]; 14 struct qq 15 { 16 int to,ne,z,lca; 17 } e[maxm],q[maxq]; 18 19 void addedge(int x,int y,int z) 20 { 21 cnt++; 22 e[cnt].to=y; 23 e[cnt].ne=h[x]; 24 e[cnt].z=z; 25 h[x]=cnt; 26 } 27 28 void addquery(int x,int y,int z) 29 { 30 q[cnt].to=y; 31 q[cnt].ne=h1[x]; 32 q[cnt].z=z; 33 h1[x]=cnt; 34 cnt++; 35 q[cnt].to=x; 36 q[cnt].ne=h1[y]; 37 q[cnt].z=z; 38 h1[y]=cnt; 39 cnt++; 40 } 41 42 void close() 43 { 44 exit(0); 45 } 46 47 int findfather(int k) 48 { 49 if (f[k]==k) 50 return k; 51 f[k]=findfather(f[k]); 52 return f[k]; 53 } 54 55 void tarjan(int k) 56 { 57 f[k]=k; 58 vis[k]=true; 59 for (int p=h[k];p!=-1;p=e[p].ne) 60 { 61 if (not vis[e[p].to]) 62 { 63 v+=e[p].z; 64 dis[e[p].to]=dis[k]+e[p].z; 65 tarjan(e[p].to); 66 v-=e[p].z; 67 f[e[p].to]=k; 68 } 69 } 70 for (int p=h1[k];p!=-1;p=q[p].ne) 71 { 72 node=q[p].to; 73 if (vis[node]) //询问的令一个点已经询问过了,表示它们的祖先就是f[另一个点] 74 { 75 int lca=findfather(node); 76 q[p].z=dis[k]+dis[node]-2*dis[lca]; 77 q[p^1].z=q[p].z; 78 } 79 } 80 } 81 82 83 void init() 84 { 85 int query=1; 86 while(scanf("%d %d %d",&n,&m,&query)!=EOF) 87 { 88 cnt=0; 89 memset(flag,false,sizeof(flag)); 90 memset(h,-1,sizeof(h)); 91 memset(h1,-1,sizeof(h1)); 92 memset(dis,0,sizeof(dis)); 93 for (int i=0;i<=n;i++) 94 f[i]=i; 95 for (int i=1;i<=m;i++) 96 { 97 scanf("%d %d %d",&x,&y,&z); 98 addedge(x,y,z); 99 addedge(y,x,z); 100 int fx=findfather(x); 101 int fy=findfather(y); 102 if (fx!=fy) 103 f[fx]=fy; 104 } 105 for (int i=1;i<=n;i++) 106 flag[findfather(i)]=true; 107 /* 108 for (int i=1;i<=n;i++) 109 if (flag[i]) 110 addedge(0,i,0); 111 */ 112 cnt=0; 113 for (int i=1;i<=query;i++) 114 { 115 scanf("%d %d",&x,&y); 116 if (f[x]!=f[y]) 117 addquery(x,y,-1); 118 else 119 addquery(x,y,0); 120 } 121 memset(f,0,sizeof(f)); 122 for (int i=1;i<=n;i++) 123 if (flag[i]) 124 { 125 memset(vis,false,sizeof(vis)); 126 tarjan(i); 127 } 128 for (int i=0;i<cnt;i+=2) 129 { 130 if (q[i].z!=-1) 131 printf("%d\n",q[i].z); 132 else 133 printf("Not connected\n"); 134 } 135 } 136 } 137 138 int main () 139 { 140 init(); 141 close(); 142 return 0; 143 }