Connections between cities
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11927 Accepted Submission(s): 2775
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.
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.
Source
Recommend
题目重现:
第十次世界大战以后,很多城市受到严重破坏,我们需要重建这些城市。 然而,所需的一些材料只能在某些地方生产。 所以我们需要将这些材料从城市运送到城市。 大多数道路在战争期间已经完全被摧毁,两个城市之间可能没有道路,也没有圈子。
现在,你的任务来了。 在给你道路的条件之后,我们想知道是否存在任何两个城市之间的路径。 如果答案是肯定的,输出它们之间的最短路径。
思路:
看到这个题,是不是又激动半天,天哪,这不又是个模板吗?!
不过,这个题比起以前的几个题来要高级那么一点点、、、这个题是森林,上几个题是棵树。
所以我们这个题进行处理的时候我们要判断两个点是否连通,也就是说他们是否在一棵树里。
我们用并查集处理就好了,剩下的就是lca的模板了、、、
代码:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 21000 using namespace std; bool vis[N]; int t,n,m,x,y,z,fx,fy,ans,tot; int fa[N],dad[N],top[N],size[N],deep[N],head[N],dis[N]; int find(int x) { if(x==dad[x]) return x; dad[x]=find(dad[x]); return dad[x]; } int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } struct Edge { int to,dis,next,from; }edge[N<<1]; int add(int x,int y,int z) { tot++; edge[tot].to=y; edge[tot].dis=z; edge[tot].next=head[x]; head[x]=tot; } int begin() { ans=0;tot=0; memset(fa,0,sizeof(fa)); memset(top,0,sizeof(top)); memset(dis,0,sizeof(dis)); memset(vis,0,sizeof(vis)); memset(edge,0,sizeof(edge)); memset(deep,0,sizeof(deep)); memset(size,0,sizeof(size)); memset(head,0,sizeof(head)); } int lca(int x,int y) { for(;top[x]!=top[y];x=fa[top[x]]) if(deep[top[x]]<deep[top[y]]) swap(x,y); if(deep[x]>deep[y]) swap(x,y); return x; } int dfs(int x) { vis[x]=true;size[x]=1; deep[x]=deep[fa[x]]+1; for(int i=head[x];i;i=edge[i].next) { int to=edge[i].to; if(fa[x]==to) continue; dis[to]=dis[x]+edge[i].dis; fa[to]=x;dfs(to); size[x]+=size[to]; } } int dfs1(int x) { int t=0; if(!top[x]) top[x]=x; for(int i=head[x];i;i=edge[i].next) { int to=edge[i].to; if(fa[x]!=to&&size[t]<size[to]) t=to; } if(t) top[t]=top[x],dfs1(t); for(int i=head[x];i;i=edge[i].next) { int to=edge[i].to; if(fa[x]!=to&&to!=t) dfs1(to); } } int pd(int x,int y) { if(find(x)==find(y)) return false; return true; } int main() { while(scanf("%d",&n)!=EOF) { m=read(),t=read();begin(); for(int i=1;i<=n;i++) dad[i]=i; for(int i=1;i<=m;i++) { x=read(),y=read(),z=read(); add(x,y,z),add(y,x,z); fx=find(x),fy=find(y); if(fx!=fy) dad[fx]=fy; } for(int i=1;i<=n;i++) if(!vis[i]) dfs(i),dfs1(i); for(int i=1;i<=t;i++) { x=read(),y=read(); if(pd(x,y)) printf("Not connected\n"); else { ans=dis[x]+dis[y]-2*dis[lca(x,y)]; printf("%d\n",ans); } } } return 0; }