【UOJ#67】新年的毒瘤 Tarjan 割点

#67. 新年的毒瘤

UOJ直接黏贴会炸...    还是戳这里吧: http://uoj.ac/problem/67#tab-statement

Solution

看到这题的标签就进来看了一眼。

想了一个比较胡搞的方法,因为删除割点就会产生多个块,那么割点是不能被割的,所以只能割非割点。

删除非割点后是棵树,说明边数是N-2...然后求一下每个点的度...

只要不是割点,并且割掉这个点剩的边是N-2条,就输出.....

然后就A了...感觉还是很科学的。 (这个Tarjan模板太好打了...顺便求了个点双...)

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define LL long long
inline int read()
{
    int 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;
}
#define MAXN 100010
int N,M,tot;
LL sum;
struct EdgeNode{int next,to,from;}edge[MAXN<<1];
int head[MAXN],cnt=1;
void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
void InsertEdge(int u,int v) {AddEdge(u,v); AddEdge(v,u);}
#define Pa pair<int,int>
vector<int>BCC[MAXN];
Pa st[MAXN]; int top;
int dfn[MAXN],low[MAXN],dfsn,cut[MAXN],bcc,belong[MAXN],d[MAXN];
void Tarjan(int now,int last)
{
    dfn[now]=low[now]=++dfsn; int son=0;
    for (int i=head[now]; i; i=edge[i].next)
        if (!dfn[edge[i].to]) 
            {
                st[++top]=make_pair(now,edge[i].to);  son++;
                Tarjan(edge[i].to,now); low[now]=min(low[now],low[edge[i].to]); 
                if (dfn[now]<=low[edge[i].to])
                    {
                        cut[now]=1; bcc++; BCC[bcc].clear(); int tnow=-1,tto=-1;
                        while (1) 
                            {
                                tnow=st[top].first,tto=st[top].second; top--;
                                if (belong[tnow]!=bcc) BCC[bcc].push_back(tnow),belong[tnow]=bcc;
                                if (belong[tto]!=bcc) BCC[bcc].push_back(tto),belong[tto]=bcc;
                                if (tnow==now && tto==edge[i].to) break;
                            }
                    }    
            }
        else if (dfn[edge[i].to]<dfn[now] && edge[i].to!=last) 
            st[++top]=make_pair(now,edge[i].to),low[now]=min(low[now],dfn[edge[i].to]);
    if (last<0 && son==1) cut[now]=0;    
}
int main()
{
    N=read(),M=read();
    for (int x,y,i=1; i<=M; i++) x=read(),y=read(),InsertEdge(x,y),d[x]++,d[y]++;
    for (int i=1; i<=N; i++) if (!dfn[i]) Tarjan(i,-1);
    for (int i=1; i<=N; i++) if (!cut[i] && d[i]==M-N+2) tot++;
    printf("%d
",tot);
    for (int i=1; i<=N; i++) if (!cut[i] && d[i]==M-N+2) printf("%d ",i); puts(""); 
    return 0;
}
原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5910783.html