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 }
View Code

 

你可能感兴趣的:(poj)