题意:
一个无向图,如果这个无向图上有一条路径能将所有的度数大于等于2的节点串联起来,而且这个无向图没有环而且是连通的,就输出Graph 2 is a caterpillar否则输出Graph 1 is not a caterpillar。
输入:
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
输出:
Graph 1 is not a caterpillar. Graph 2 is a caterpillar.
分析:
当时因为审题的原因,没有读出这个无向图是连通的,而且不能有环,导致错了好几遍。我先构建了两个点之间的关系,如果两点
有关系,就用一个二维数组标记一下,之后判断如果两个这样的点连接,就统计一下该点的连接分支,如果连接分支大于3时,就表
示一定有点不在这一条路径上。判断环和不连通的时候,我用了一个小技巧:先将该图变成一个简单图,即对边去重,之后统计边
数。如边数<n-1就表示不连通,若边数>=n就表示有环。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<string>
#include<cmath>
#include<vector>
using namespace std;
int vis[105],vis2[105][105];
int num[105],num2[105];
int kcase=0;
int main()
{
int n,m;
while(~scanf("%d",&n)&&n)
{
scanf("%d",&m);
memset(num,0,sizeof(num));
memset(vis,0,sizeof(vis));
memset(vis2,0,sizeof(vis2));
memset(num2,0,sizeof(num2));
for(int i=1; i<=m; i++)
{
for(int i=1; i<=1; i++)
{
int a,b;
scanf("%d%d",&a,&b);
vis2[a][b]=1;
num[a]++;
num[b]++;
}
}
int l_num=0;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(vis2[i][j]==1)
l_num++;
}
}
printf("Graph %d is ",++kcase);
if(l_num>=n)
{
printf("not a caterpillar.\n");
}
else if(l_num<n-1)
{
printf("not a caterpillar.\n");
}
else
{
for(int i=1; i<=n; i++)
{
if(num[i]>=2)
{
vis[i]=1;
}
}
for(int i=1; i<=n; i++)
{
if(vis[i])
{
for(int j=1; j<=n; j++)
{
if(vis[j]&&vis2[i][j])
{
num2[i]++;
num2[j]++;
continue;
}
}
}
}
int f=1;
for(int i=1; i<=n; i++)
{
if(num2[i]>=3)
{
printf("not a caterpillar.\n");
f=0;
break;
}
}
if(f==1)
{
printf("a caterpillar.\n");
}
}
}
return 0;
}