不容易啊不容易 搞了够四个小时
题意:所有的度数大于1的点(与之有边的点不止一个的点)必须在最长路上,并且不存在环和孤点,问给出的图是否满足以上条件。
思路:记录好边的度数之后,遍历度数,如果有是0的便存在孤点,否则继续;然后拓扑排序判环;然后求树的直径并在此过程中记录路径,然后遍历度数 看度数>1的点是不是都在这条路上(大佬的做法:直接求树的直径,因为权值都是1,树的直径+1等于点的个数,判断点的个数(需要减去两头度数为1的端点)是否等于整个图中度数大于1的点个数)
代码写的乱的一批 但是能过我就嘿嘿嘿
#include<iostream>
#include<algorithm>
#include<string.h>
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#define ll long long
#define inf 0x3f3f3f
using namespace std;
const int maxn=1e3+5;
struct edg{
int next,to,val;
}edge[maxn*maxn];
int cnt=1,head[maxn],n,m,deg[maxn];
void addedge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
edge[cnt].val=1;
head[u]=cnt++;
}
int top()
{
int tdeg[maxn];
memcpy(tdeg,deg,sizeof deg);
queue<int> q;
for(int i=1;i<=n;i++)
if(tdeg[i]==1)
q.push(i);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
tdeg[v]--;
if(tdeg[v]==1)
q.push(v);
}
}
for(int i=1;i<=n;i++)
{
if(tdeg[i]>0)
return 1;
}
return 0;
}
int final,k,ans=0,lujing[maxn],tlujing[maxn],book[maxn],check[maxn];
void dfs(int u,int dis,int step)
{
book[u]=1;
if(dis>ans)
{
ans=dis;
final=u;
for(int i=0;i<step;i++)
lujing[i]=tlujing[i];
k=step;
}
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(!book[v])
{
tlujing[step]=v;
dfs(v,dis+edge[i].val,step+1);
}
}
}
int main()
{
int ok=1;
while(scanf("%d",&n)&&n)
{
scanf("%d",&m);
memset(head,0,sizeof(head));
cnt=1;
memset(deg,0,sizeof deg);
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
deg[v]++;
deg[u]++;
}
int flag=1;
for(int i=1;i<=n;i++)
if(!deg[i])
{
flag=0;
break;
}
if(!flag||top())
flag=0;
ans=0;
memset(book,0,sizeof book);
dfs(1,0,1);
ans=0;
memset(book,0,sizeof book);
tlujing[0]=final;
dfs(final,0,1);
memset(check,0,sizeof check);
for(int i=0;i<k;i++)
check[lujing[i]]=1;
for(int i=1;i<=n;i++)
{
if(deg[i]>1)
{
if(!check[i])
{
flag=0;
break;
}
}
}
if(!flag)
printf("Graph %d is not a caterpillar.\n",ok++);
else printf("Graph %d is a caterpillar.\n",ok++);
}
}