题目给出的判断条件有三:
无环,连通,存在一条链囊括所有的的结点或者邻接所有顶点。
前两条件就不说了,第三个其实就是看一个结点它的儿子子树之中是否有大于2棵结点数超过1,另外,如果恰有2棵,还需看父亲祖辈是否有超过一个的结点。
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=105,M=305; 6 int head[N],nc; 7 struct edge 8 { 9 int to,next; 10 }edge[M*2]; 11 void add(int a,int b) 12 { 13 edge[nc].next=head[a];edge[nc].to=b;head[a]=nc++; 14 edge[nc].next=head[b];edge[nc].to=a;head[b]=nc++; 15 } 16 int tot[N],n,m; 17 bool vis[N]; 18 bool dfs(int now,int fa) 19 { 20 int cnt=0; 21 tot[now]=1; 22 vis[now]=true; 23 for(int i=head[now];i!=-1;i=edge[i].next) 24 { 25 int t=edge[i].to; 26 if(!vis[t]) 27 { 28 if(!dfs(t,now)) 29 return false; 30 if(tot[t]>1) 31 { 32 cnt++; 33 if(cnt>2) 34 return false; 35 } 36 tot[now]+=tot[t]; 37 } 38 else if(vis[t]&&t!=fa) 39 return false; 40 } 41 if(cnt==2&&n-tot[now]>1) 42 return false; 43 return true; 44 } 45 int main() 46 { 47 int ca=0; 48 while(scanf("%d",&n)&&n) 49 { 50 bool flag=true; 51 scanf("%d",&m); 52 if(m!=n-1) 53 flag=false; 54 nc=0; 55 memset(head,-1,sizeof(head)); 56 for(int i=0;i<m;i++) 57 { 58 int a,b; 59 scanf("%d%d",&a,&b); 60 add(a,b); 61 } 62 memset(vis,false,sizeof(vis)); 63 if(!flag) 64 { 65 printf("Graph %d is not a caterpillar.\n",++ca); 66 continue; 67 } 68 else if(!dfs(1,1)) 69 printf("Graph %d is not a caterpillar.\n",++ca); 70 else 71 { 72 int i; 73 for(i=1;i<=n;i++) 74 if(!vis[i]) 75 break; 76 if(i<=n) 77 printf("Graph %d is not a caterpillar.\n",++ca); 78 else 79 printf("Graph %d is a caterpillar.\n",++ca); 80 } 81 } 82 return 0; 83 }