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.
",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.
",t++);
123         }else
124             printf("Graph %d is not a caterpillar.
",t++);
125     }
126     return 0;
127 }
View Code
原文地址:https://www.cnblogs.com/wally/p/3280831.html