http://uoj.ac/problem/67
中文题目:
给定一个无向图,问你当切割完一个点后,剩下的点连接成一个树。
问你切割哪些点,按照顺序从小到大输出。
首先 割点是不能切的,割点切了就不是连通图了。
其次 我们发现最后的题意要求是图。设切的点的度为x
则存在 (n-x)+1=m-1 (m是点,n是边,切了点后少了x个边后,构成了树的关系,即边加1等于 点的个数)
于是乎,这个题,也可以用先进的targin来做了。
割点有关知识
对于一个节点u如果他的孩子节点v的low值大于等于u的出生日期dfn值,进行下一步判断,如果u是我们选的根节点,我们还需要判断一下他的孩子节点的个数是否大于一,如果大于一则他是割点,反之不是。如果u不是根节点,那他就是割点了
有向图无向图都一样。O(∩_∩)O哈哈~
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stack>
#include <vector>
#include <cstring>
using namespace std;
typedef long long ll;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int maxn=200011;
int dfn[maxn];//dfs顺序。和一种求lca的序不一样??
int low[maxn];//最小能够到达的点。
int index1;//记录时间的标号
bool state[maxn];//是否在栈里.
stack<int>s;
vector<int>G[maxn];
int cnt[maxn];
int num[maxn];
int scc_one;
int du[maxn];
/*void tarjan(int u,int pre)
{ dfn[u]=low[u]=++index1;
s.push(u);
state[u]=true;
for(int i=0;i<G[u].size();i++){
if(G[u][i]==pre) continue;
else if(!dfn[G[u][i]]){
tarjan(G[u][i],u);
low[u]=min(low[G[u][i]],low[u]);
}
else if(state[G[u][i]])
low[u]=min(low[u],dfn[G[u][i]]);//在次遇见你。。
}
if(low[u]>=dfn[pre])
{ if(pre==1)
{ scc_one++;
}
else
cnt[pre]=1;
}
}*/
void tarjan(int u,int pre)
{
dfn[u]=low[u]=++index1;
state[u]=1;
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(v==pre)
continue;
if(!state[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else if(state[v]==1)
low[u]=min(low[u],dfn[v]);
}
if(dfn[pre]<=low[u])
{
if(pre==1)
{
scc_one++;
}
else
cnt[pre]=1;
}
}
int main()
{ int t;
int a,b;
int m,n;
m=read();n=read();
for(int i=1;i<=n;i++){
a=read();b=read();
G[a].push_back(b);
G[b].push_back(a);
du[a]++;
du[b]++;
}
memset(state,false,sizeof(state));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(cnt,0,sizeof(cnt));
tarjan(1,0);
if(scc_one>1)
cnt[1]=1;
int ans=0;
for(int i=1;i<=m;i++)
if(!cnt[i]&&du[i]==n-m+2)
ans++;
printf("%d\n",ans);
for(int i=1;i<=m;i++){
if(!cnt[i]&&du[i]==n-m+2)
printf("%d ",i);
}
printf("\n");
return 0;
}