首页 > 技术文章 > poj 2117 Electricity

yanlifneg 2016-09-04 16:29 原文

/*
Tarjan求割点 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#define maxn 10010
using namespace std;
int n,m,num,head[maxn],low[maxn],dfn[maxn],f[maxn],father[maxn];
int point[maxn],topt,sum;
struct node{
    int v,pre;
}e[maxn*200];
stack<int>s;
int init(){
    int x=0;char s=getchar();
    while(s<'0'||s>'9')s=getchar();
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x;
}
void Clear(){
    memset(head,-1,sizeof(head));
    memset(low,0,sizeof(low));
    memset(dfn,0,sizeof(dfn));
    memset(f,0,sizeof(f));
    memset(point,0,sizeof(point));
    num=topt=sum=0;
    while(!s.empty())s.pop();
}
void Add(int from,int to){
    e[num].v=to;
    e[num].pre=head[from];
    head[from]=num++;
}
void Tarjan(int x,int fa,int E){
    father[x]=fa;
    dfn[x]=low[x]=++topt;
    f[x]=1;s.push(x);
    int sc=0;
    for(int i=head[x];i!=-1;i=e[i].pre){
        int v=e[i].v;
        if(i==(E^1))continue;
        if(dfn[v]==0){
            sc++;
            Tarjan(v,x,i);low[x]=min(low[x],low[v]);
            if(low[v]>=dfn[x])point[x]++;
        }
        else if(f[v])low[x]=min(low[x],dfn[v]);
    }
    if(fa<0&&sc==1)point[x]=0;
    if(low[x]==dfn[x]){
        while(s.top()!=x){
            f[s.top()]=0;s.pop();
        }
        f[s.top()]=0;s.pop();
    }
}
void Init(){
    for(int i=1;i<=m;i++){
        int u,v;
        u=init();v=init();
        u++;v++;
        Add(u,v);Add(v,u);
    }
    for(int i=1;i<=n;i++)
        if(dfn[i]==0){
            sum++;Tarjan(i,-1,-1);
        }
}
void Solve(){
    int mxx=-100000;
    for(int u=1;u<=n;u++){
        if(father[u]==-1){
            point[u]--;
        }
        mxx=max(mxx,point[u]);
    }
    printf("%d\n",sum+mxx);
}
int main()
{
    while(1){
        n=init();m=init();
        if(n==0&&m==0)break;
        Clear();
        Init();
        Solve();
    }
}

 

推荐阅读