您的位置:首页 > 其它

【UOJ 67】【JZOJ 4679】种树

2016-08-11 19:51 260 查看

Description



抽象题意:给出一个图,求有多少种方案使删掉一个点后图变成一棵树。

Solution

原图有n个点,m条边,

删掉一个店后为(n-1)个点的图,

那么删掉这个点后图减小了(m-n+2)条边,

割点一定不能被删,

所以用tarjan特判一下即可

复杂度:O(n)

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define efo(i,q) for(int i=A[q];i;i=B[i][0])
using namespace std;
const int N=100500,maxlongint=2147483640;
int read(int &n)
{
char ch=' ';int q=0,w=1;
for(;(ch!='-')&&((ch<'0')||(ch>'9'));ch=getchar());
if(ch=='-')w=-1,ch=getchar();
for(;ch>='0' && ch<='9';ch=getchar())q=q*10+ch-48;n=q*w;return n;
}
int m,n,ans;
int s
,b
,b1
;
int za
,a
,FA
;
bool z
;
int B0,A
,B[N*2][2];
void link(int q,int w)
{
B[++B0][0]=A[q],A[q]=B0,B[B0][1]=w,a[q]++;
B[++B0][0]=A[w],A[w]=B0,B[B0][1]=q,a[w]++;
}
int tarjan(int q,int fa)
{
FA[q]=fa;
za[b[q]=++za[0]]=q;z[q]=1;b1[q]=b[q];
efo(i,q)if(B[i][1]!=fa)
{
if(z[B[i][1]])b[q]=min(b[q],b1[B[i][1]]);
else b[q]=min(b[q],tarjan(B[i][1],q));
}
za[0]--;
return b[q];
}
int main()
{
int q,w;
read(n);read(m);
fo(i,1,m)read(q),read(w),link(q,w);
tarjan(1,1);
fo(i,1,n)if(m-a[i]==n-2)
{
bool Z=1;
efo(j,i)if(b[B[j][1]]>b1[i])Z=0;
if(Z)s[++s[0]]=i;
}
printf("%d\n",s[0]);
fo(i,1,s[0])printf("%d ",s[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: