标签:bst 一个 alt win content == 之间 can cas
InputThe Input consists of multiple test cases. The first line of each test case contains three integers, N ( 3 <= N <= 5000 ), M ( 0 <= M <= 10000 ) and Q ( 1 <= Q <= 1000 ). which are the number of enterprises, the number of the financial trade relations and the number of queries.
The next M lines, each line contains two integers, u, v ( 0 <= u, v < N && u != v ), which means enterpirse u and enterprise v have trade relations, you can assume that the input will not has parallel edge.
The next Q lines, each line contains two integers, u, v ( 0 <= u, v < N && u != v ), which means entrepreneurs will ask you the financial safety of enterpirse u and enterprise v.
The last test case is followed by three zeros on a single line, which means the end of the input.OutputFor each case, output the test case number formated as sample output. Then for each query, output "zero" if there is no independent financial chains between those two enterprises, output "one" if there is only one such chains, or output "two or more".Sample Input
3 1 2 0 1 0 2 1 0 4 4 2 0 1 0 2 1 2 2 3 1 2 1 3 0 0 0
Sample Output
Case 1: zero one Case 2: two or more one
题意:
给你一个(保证输入无重边,无自环)无向图,然后有下面Q条询问,每条询问为:问你u点与v点之间有几条(除了首尾两点外,其他点不重复)的路径.如果有0条或1条输出0或1,如果有2条以上,输出”two or more”.
分析:
首先如果u点与v点不连通,直接输出0即可.(用并查集实现)
然后如果u点与v点属于同一个点-双连通分量,输出two or more.(这里有特例,两点一边的点-双连通分量应该输出1)
自己写的代码已知wrong不知道为什么,哪位大佬看一看谢谢。。
1 #include<cstring> 2 #include<cmath> 3 #include<iostream> 4 #include<cstdio> 5 #include<algorithm> 6 #include<map> 7 using namespace std; 8 9 int n,m,q,TAK,col,tim,top,tot; 10 int a[5007],color[5007],dfn[5007],low[5007],stack[5007],ins[5007]; 11 int cnt,head[5007],Next[20007],rea[20007]; 12 struct Node 13 { 14 int x,y; 15 }b[1007]; 16 map<int,int>p; 17 18 void add(int u,int v) 19 { 20 Next[++cnt]=head[u]; 21 head[u]=cnt; 22 rea[cnt]=v; 23 } 24 void Tarjan(int u,int fa) 25 { 26 int num=0;color[u]=col; 27 dfn[u]=low[u]=++tim; 28 stack[++top]=u,ins[u]=1; 29 for (int i=head[u];i!=-1;i=Next[i]) 30 { 31 int v=rea[i]; 32 if (v==fa) continue; 33 if (!dfn[v]) 34 { 35 Tarjan(v,u);num++; 36 low[u]=min(low[u],low[v]); 37 if (low[v]>=dfn[u]) 38 { 39 tot=0; 40 int x=-1; 41 while(x!=u) 42 { 43 x=stack[top--]; 44 ins[x]=0; 45 a[++tot]=x; 46 } 47 stack[++top]=u,ins[u]=1; 48 if (tot==2) continue; 49 for (int j=1;j<tot;j++) 50 for (int k=j+1;k<=tot;k++) 51 { 52 int x=a[j],y=a[k]; 53 if (x>y) swap(x,y); 54 if (p[x*n+y]==-1) p[x*n+y]=1; 55 } 56 } 57 } 58 else low[u]=min(low[u],dfn[v]); 59 } 60 } 61 int main() 62 { 63 while(~scanf("%d%d%d",&n,&m,&q)&&(n+m+q)) 64 { 65 printf("Case %d:\n",++TAK); 66 cnt=top=tim=0;p.clear(); 67 memset(dfn,0,sizeof(dfn)); 68 memset(low,0,sizeof(low)); 69 memset(color,0,sizeof(color)); 70 memset(head,-1,sizeof(head)); 71 for (int i=1,x,y;i<=m;i++) 72 { 73 scanf("%d%d",&x,&y); 74 x++,y++; 75 add(x,y),add(y,x); 76 } 77 for (int i=1;i<=q;i++) 78 { 79 scanf("%d%d",&b[i].x,&b[i].y); 80 b[i].x++,b[i].y++; 81 if (b[i].x>b[i].y) swap(b[i].x,b[i].y); 82 p[b[i].x*n+b[i].y]=-1; 83 } 84 for (int i=1;i<=n;i++) 85 if (!dfn[i]) 86 { 87 col=i; 88 Tarjan(i,-1); 89 } 90 for (int i=1;i<=q;i++) 91 if (color[b[i].x]!=color[b[i].y]) printf("zero\n"); 92 else if (p[b[i].x*n+b[i].y]==-1) printf("one\n"); 93 else printf("two or more\n"); 94 } 95 }
HDU 3749 Financial Crisis(点-双连通分量)
标签:bst 一个 alt win content == 之间 can cas
原文地址:http://www.cnblogs.com/fengzhiyuan/p/7747698.html