poj 3310(并查集判环,图的连通性,树上最长直径路径标记)
题目链接:http://poj.org/problem?id=3310
思路:首先是判断图的连通性,以及是否有环存在,这里我们可以用并查集判断,然后就是找2次dfs找树上最长直径了,并且对树上最长直径上的点进行标记,于是根据题意我们可以发现,如果这个图是“caterpillar”的话,那么他所有的边要么两端都在树上最长直径上,要么就是其中一端在,于是我们可以再次dfs进行判断就可以了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 111 7 8 struct Edge{ 9 int v,next; 10 }edge[MAXN*MAXN]; 11 12 int n,m,NE; 13 int head[MAXN]; 14 15 void Insert(int u,int v) 16 { 17 edge[NE].v=v; 18 edge[NE].next=head[u]; 19 head[u]=NE++; 20 } 21 22 int parent[MAXN]; 23 24 void Initiate() 25 { 26 for(int i=1;i<=n;i++){ 27 parent[i]=i; 28 } 29 } 30 31 int Find(int x) 32 { 33 if(x==parent[x]){ 34 return parent[x]; 35 } 36 parent[x]=Find(parent[x]); 37 return parent[x]; 38 } 39 40 bool Judge() 41 { 42 int cnt=0; 43 for(int i=1;i<=n;i++){ 44 if(parent[Find(i)]==i)cnt++; 45 } 46 return cnt==1; 47 } 48 49 int dep[MAXN]; 50 int path[MAXN]; 51 bool mark[MAXN],vis[MAXN]; 52 53 void dfs_dep(int u,int father) 54 { 55 for(int i=head[u];i!=-1;i=edge[i].next){ 56 int v=edge[i].v; 57 if(v==father)continue; 58 dep[v]=dep[u]+1; 59 path[v]=u; 60 dfs_dep(v,u); 61 } 62 } 63 64 bool dfs(int u) 65 { 66 vis[u]=true; 67 for(int i=head[u];i!=-1;i=edge[i].next){ 68 int v=edge[i].v; 69 if(vis[v])continue; 70 if(mark[u]||mark[v]){ 71 if(dfs(v))return true; 72 } 73 return false; 74 } 75 return true; 76 } 77 78 79 int main() 80 { 81 // freopen("1.txt","r",stdin); 82 int u,v,st,ed,tmp,t=1; 83 while(~scanf("%d",&n)&&n){ 84 scanf("%d",&m); 85 NE=0; 86 memset(head,-1,sizeof(head)); 87 Initiate(); 88 bool flag=true; 89 while(m--){ 90 scanf("%d %d",&u,&v); 91 Insert(u,v); 92 Insert(v,u); 93 if(Find(u)!=Find(v))parent[Find(u)]=Find(v); 94 else flag=false; 95 } 96 if(!flag||!Judge()){ 97 printf("Graph %d is not a caterpillar.\n",t++); 98 continue; 99 } 100 dep[1]=0; 101 dfs_dep(1,-1); 102 ed=1; 103 for(int i=1;i<=n;i++){ 104 if(dep[i]>dep[ed])ed=i; 105 } 106 dep[st=ed]=0; 107 dfs_dep(st,-1); 108 ed=1; 109 for(int i=1;i<=n;i++){ 110 if(dep[i]>dep[ed])ed=i; 111 } 112 memset(mark,false,sizeof(mark)); 113 path[st]=-1; 114 mark[st]=true; 115 tmp=ed; 116 while(path[tmp]!=-1){ 117 mark[tmp]=true; 118 tmp=path[tmp]; 119 } 120 memset(vis,false,sizeof(vis)); 121 if(dfs(1)){ 122 printf("Graph %d is a caterpillar.\n",t++); 123 }else 124 printf("Graph %d is not a caterpillar.\n",t++); 125 } 126 return 0; 127 }