hdu2767强连通+缩点 如果让我说:我只能说,实力决定一切

来源:互联网 发布:淘宝店铺代销发货地址 编辑:程序博客网 时间:2024/04/30 12:45

题意:给你一个有向图,然后添边,让该图成为连通分量为1的连通图,需要添加的边数

思路:强连通+缩点,记录每个连通分量的入度和初度为0 的个数。找一个最大的值

 刚开始自己认为如果一个连通分量的入度为1,那么它的出度一定为0,这是极大的错误。

 

#include<iostream>#include<algorithm>#include<cstdio>#include<string.h>#include<vector>#include<stack>#define maxn 10010using namespace std;stack<int>S;vector<int>gra[2*maxn];int T,n,m;int dfn[2*maxn],low[2*maxn],vis[2*maxn],belong[2*maxn],ind[2*maxn],outd[2*maxn];int sum;int tem;int MIN(int a,int b){    return a>b?b:a;}void tarjan(int pox){    vis[pox]=2;    dfn[pox]=low[pox]=++sum;    S.push(pox);    for(int i=0; i<gra[pox].size(); i++)    {        int t=gra[pox][i];        if(!dfn[t])        {            tarjan(t);            low[pox]=MIN(low[pox],low[t]);        }        else if(vis[t]==2)        {            low[pox]=MIN(low[pox],dfn[t]);        }    }    if(low[pox]==dfn[pox])    {        tem++;        while(!S.empty())        {            int gh=S.top();            S.pop();            belong[gh]=tem;            ind[gh]=0;            outd[gh]=0;            vis[gh]=1;            if(gh==pox)                break;        }    }}int main(){    int a,b;    int inMax,outMax;    while(scanf("%d",&T)!=EOF)    {        while(T--)        {            tem=sum=0;            inMax=outMax=0;            scanf("%d%d",&n,&m);            memset(dfn,0,sizeof(dfn));            memset(vis,0,sizeof(vis));            memset(low,0,sizeof(low));            for(int i=0; i<2*maxn; i++)                gra[i].clear();            while(!S.empty())                S.pop();            for(int i=0; i<m; i++)            {                scanf("%d%d",&a,&b);                gra[a].push_back(b);            }            for(int i=1; i<=n; i++)                if(!dfn[i])                    tarjan(i);            if(tem==1)            {                printf("0\n");                continue;            }            for(int j=1; j<=n; j++)                for(int i=0; i<gra[j].size(); i++) //记录每个节点的入度:                {                    if(belong[j]!=belong[gra[j][i]])                    {                        outd[belong[j]]++;                         ind[belong[gra[j][i]]]++;                    }                }        //    printf("tem=%d\n",tem);            for(int i=1; i<=tem; i++)            {                if(!ind[i])                  inMax++;                if(!outd[i])                  outMax++;            }            /*                if(ind[i]==1)                    inMax++;                else                    outMax++;            */            printf("%d\n",inMax>outMax?inMax:outMax);        }    }    return 0;}