您的位置:首页 > 其它

【UOJ67】【JZOJ4679】种树

2016-08-11 19:20 246 查看

Description



原题在:http://uoj.ac/problem/67

Solution

首先确定树的概念:有n个点,n-1条边的无向连通图。

那么现在我们有n个点m条边,我们现在要删除一个点u首先要满足原图要联通,然后才满足树的条件。

那么,用Tarjan求出所有割点,那么非割点去掉后仍保持联通,那么在此基础上判断是否是树即可。

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 100001
#define M 200001
#define ll long long
using namespace std;
int to[M],next[M],last[M],num=0;
int ds
;
int c
;
bool bz
;
bool r
;
void link(int x,int y)
{
num++;
to[num]=y;
next[num]=last[x];
last[x]=num;
}
int dfn
,low
;
int dep=0;
int cut
;
void tarjan(int x)
{
low[x]=dfn[x]=++dep;
for(int i=last[x];i;i=next[i])
{
int v=to[i];
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
if(low[v]>=dfn[x]) cut[x]++;
}
else low[x]=min(low[x],dfn[v]);
}
}
int main()
{
int n,m;
cin>>n>>m;
fo(i,1,m)
{
int u,v;
scanf("%d %d",&u,&v);
ds[u]++;
ds[v]++;
link(u,v);
link(v,u);
}
fo(i,1,n) if(!dfn[i]) cut[i]--,tarjan(i);
fo(i,1,n)
if(cut[i]<=0)
{
if(n-2==m-ds[i]) c[++c[0]]=i;
}
cout<<c[0]<<endl;
fo(i,1,c[0]) printf("%d ",c[i]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: