HDU2767.Proving Equivalences等价性证明——SCC

来源:互联网 发布:手机淘宝免费注册账号 编辑:程序博客网 时间:2024/06/07 02:05

http://acm.hdu.edu.cn/showproblem.php?pid=2767

题目描述:
给定n个结点m条边的有向图,求添加最少的边使得新图变为强连通图

分析:
首先找出强连通分量,然后把每个强连通分量缩成一个点,得到一个DAG。设有a个结点的入度为0,b个结点的出度为0,则答案为max(a,b)
。当原图已经强连通时,答案为0

一个含有n个点的图,至少要有n条边才能强连通,即每个点至少有一个入度和一个出度。对于得到的DAG,因为每增加一条边,会同时增加一个入度和一个出度,所以最少需要max(a,b)

#include<cstring>#include<cstdio>#include<algorithm>#include<vector>#define pb push_backconst int MAXN=20010;using namespace std;vector<int> g[MAXN];int scc_cnt,sccno[MAXN],dfn[MAXN],low[MAXN],dfs_clock;int Stack[MAXN],top;bool instack[MAXN];int in[MAXN],out[MAXN];void init(int n){    for(int i=1;i<=n;++i) g[i].clear();    scc_cnt=dfs_clock=0;    memset(in,0,sizeof(in));    memset(out,0,sizeof(out));    memset(dfn,0,sizeof(dfn));    memset(sccno,0,sizeof(sccno));}void Tarjan(int u){    int v;    low[u]=dfn[u]=++dfs_clock;    Stack[top++]=u;    instack[u]=1;    for(int i=0;i<g[u].size();++i){        v=g[u][i];        if(!dfn[v]){            Tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(instack[v]&&low[u]>dfn[v])            low[u]=dfn[v];    }    if(low[u]==dfn[u]){        scc_cnt++;        for(;;){            v=Stack[--top];            sccno[v]=scc_cnt;            instack[v]=0;            if(v==u) break;        }    }}void find_scc(int n){    for(int u=1;u<=n;++u){        if(!dfn[u])            Tarjan(u);    }}void solve(int n){    find_scc(n);    int v;    if(scc_cnt==1){printf("0\n");return ;}    for(int u=1;u<=n;++u){        for(int i=0;i<g[u].size();++i){            v=g[u][i];            if(sccno[v]!=sccno[u]){                out[sccno[u]]++;                in[sccno[v]]++;            }        }    }    int a=0,b=0;    for(int i=1;i<=scc_cnt;++i){        if(!in[i]) a++;        if(!out[i]) b++;    }    printf("%d\n",max(a,b));}int main(){    int T,n,m,u,v;    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        init(n);        while(m--){            scanf("%d%d",&u,&v);            g[u].pb(v);        }        solve(n);    }    return 0;}
0 0
原创粉丝点击