#Caterpillar
An undirected graph is called a caterpillar if it is connected, has no cycles, and there is a path in the graph where every node is either on this path or a neighbor of a node on the path. This path is called the spine of the caterpillar and the spine may not be unique. You are simply going to check graphs to see if they are caterpillars.
For example, the left graph below is not a caterpillar, but the right graph is. One possible spine is
shown by dots.
Input
There will be multiple test cases. Each test case starts with a line containing n indicating the number of nodes, numbered 1 through n (a value of n = 0 indicates end-of-input). The next line will contain an integer e indicating the number of edges. Starting on the following line will be e pairs n1 n2 indicating an undirected edge between nodes n1 and n1. This information may span multiple lines. You may assume that n ≤ 100 and e ≤ 300. Do not assume that the graphs in the test cases are connected or acyclic.
Output
For each test case generate one line of output. This line should either be
Graph g is a caterpillar.
1
or
Graph g is not a caterpillar.
as appropriate, where g is the number of the graph, starting at 1.
Sample Input
22
21
1 2 2 3 2 4 2 5 2 6 6 7 6 10 10 8 9 10 10 12 11 12 12 13 12 17
18 17 15 17 15 14 16 15 17 20 20 21 20 22 20 19
16
15
1 2 2 3 5 2 4 2 2 6 6 7 6 8 6 9 9 10 10 12 10 11 10 14 10 13 13 16 13 15
0
Sample Output
Graph 1 is not a caterpillar.
Graph 2 is a caterpillar.
题目链接
题目大体意思就是给你图,然后这个图要求要是一棵树,并且这棵树有一条主干,不在主干上的点必须以悬挂点的形式挂在主干上,不能挂在在主干的分支上,也就是在分支上不能出现小的分支。这个当时看了以后,先不说看不懂题意,问了队友题意之后还是一脸懵逼,这要怎么做?后来队友给我发了个题解的代码,一下子就被折服了,太强了。
题解的主要思想是:根据题目要求,我们的树不能出现多重分支。也就是说你如果把在这棵树挂在主干上的悬挂点全部都去掉的话,那么就只剩了一条主干,不可能存在其他分支。并且这个主干的两边一定原来连了许多悬挂边,后来成为了主干的两侧,也变成了悬挂边,这样我们记录一下有这样变化的点或者边,如果大于2就说明除了两侧,还有其他分支,是不符合题意的。用两个数组做记录,剩下的就是判断是不是一棵树了,用并查集就可以了。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
struct node{
ll y,next_s;
}side[601];
ll n,f[101],in[101],out[101],cnt,head[101];
void init(){
memset(head,-1,sizeof(head));
cnt=0;
}
ll find(ll x){
ll r=x;
while(r!=f[r]){
r=f[r];
}
ll j=x;
while(f[j]!=r){
x=f[j];
f[j]=r;
j=x;
}
return r;
}
void add(ll x,ll y){
side[cnt].y=y;
side[cnt].next_s=head[x];
head[x]=cnt++;
}
ll judge(){
for(int i=1;i<=n;i++){
if(in[i]==1){//悬挂点
for(int j=head[i];j!=-1;j=side[j].next_s){
out[side[j].y]--;//将所有悬挂点链接的点的出度减一
}
}
}
ll cn=0;
//找 起初不是悬挂点,但删边之后称为悬挂点的数目
//如果是毛虫图,cn肯定为2;
//因为毛虫图删边之后只剩下了主干,最多两个头上的悬挂点
for(int i=1;i<=n;i++){
if(in[i]>1&&out[i]==1){
cn++;
}
}
if(cn>2)
return 0;
else return 1;
}
int main(){
ll e,cnt_s=1;
while(~scanf("%lld",&n)&&n){
init();
scanf("%lld",&e);
for(int i=0;i<=n;i++){
f[i]=i;
in[i]=0;
out[i]=0;
}
ll sign=1;
for(int i=0;i<e;i++){
ll x,y;
scanf("%lld %lld",&x,&y);
add(x,y);add(y,x);
in[x]++;in[y]++;out[x]++;out[y]++;//无向图入度出度都加一
ll tx=find(x);
ll ty=find(y);
if(tx!=ty)
f[tx]=ty;
else sign=0;//如果tx=ty,说明有环
}
if(sign==0){//有环
printf("Graph %lld is not a caterpillar.\n",cnt_s++);
continue;
}
ll cn=0;
for(int i=1;i<=n;i++){
if(f[i]==i){//检测有几个连通分支数
cn++;
}
}
if(cn>1){//超过一个,不连通
printf("Graph %lld is not a caterpillar.\n",cnt_s++);
continue;
}
if(!judge())
printf("Graph %lld is not a caterpillar.\n",cnt_s++);
else printf("Graph %lld is a caterpillar.\n",cnt_s++);
}
return 0;
}
树的直径:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
struct node{
ll id;
ll d;
ll next_s;
}side[605];
ll n,head[101],flag[101],cnt,f[101],dis[101];
void init(){
memset(head,-1,sizeof(head));
cnt=0;
}
struct Node{
ll id;
ll d;
};
void add(ll x,ll y,ll d){
side[cnt].d=d;
side[cnt].id=y;
side[cnt].next_s=head[x];
head[x]=cnt++;
}
ll find(ll x){
ll r=x;
while(r!=f[r]){
r=f[r];
}
ll j=x;
while(f[j]!=r){
x=f[j];
f[j]=r;
j=x;
}
return r;
}
ll bfs(ll x,ll num){
for(int i=1;i<=n;i++){
flag[i]=0;
f[i]=i;
}
Node temp;
temp.id=x;
temp.d=0;
queue<Node> p;
p.push(temp);
flag[x]=1;
ll index=x;
while(!p.empty()){
temp=p.front();
p.pop();
for(int i=head[temp.id];i!=-1;i=side[i].next_s){
if(!flag[side[i].id]){
Node t;
t.id=side[i].id;
t.d=temp.d+side[i].d;
if(num<t.d){
index=side[i].id;
num=t.d;
}
p.push(t);
f[t.id]=temp.id;
flag[side[i].id]=1;
}
}
}
return index;
}
int main(){
ll e,cnt_s=1;
while(cin>>n&&n){
init();
for(int i=1;i<=n;i++){
f[i]=i;
}
cin>>e;
ll cn=0,sign=0;
for(int i=1;i<=e;i++){
ll x,y;
cin>>x>>y;
add(x,y,1);
add(y,x,1);
ll tx=find(x);
ll ty=find(y);
if(tx!=ty){
f[tx]=ty;
cn++;
}
else sign=1;
}
if(cn<n-1||sign==1){
cout<<"Graph "<<cnt_s++<<" is not a caterpillar."<<endl;
continue;
}
ll book=bfs(1,0);
ll en=bfs(book,0);
for(int i=1;i<=n;i++){
flag[i]=0;
}
for(int i=en;f[i]!=i;i=f[i]){
flag[i]=1;
for(int j=head[i];j!=-1;j=side[j].next_s){
flag[side[j].id]=1;
}
}
ll cnt_k=0;
for(int i=1;i<=n;i++){
if(!flag[i]){
cnt_k++;
}
}
if(cnt_k>0){
cout<<"Graph "<<cnt_s++<<" is not a caterpillar."<<endl;
}
else cout<<"Graph "<<cnt_s++<<" is a caterpillar."<<endl;
}
return 0;
}