HDU 4635


题意:问最多能添加多少条边使图仍为简单单向图(没有重边和环)且非强连通,若已经是强连通了,输出-1;


分析:tarjan求强连通缩点,具体参考http://blog.csdn.net/Jarily/article/details/13627397



#include 
#include
#include
#include
#include
#define N  100005
#include
#include
using namespace std;
vector v[N];
stack s;
int n,cnt,index,dfn[N],low[N],id[N],in[N],out[N],instack[N],cnt_in,cnt_out,num[N];
void init(){
    for(int i=1;i<=n;i++){
        dfn[i]=0;
        low[i]=0;
        in[i]=0;
        out[i]=0;
        instack[i]=0;
        cnt_in=0;
        cnt_out=0;
        v[i].clear();
    }
    memset(num,0,sizeof(num));
    index=0;
    cnt=0;
    while(!s.empty())
    s.pop();
}
void tarjan(int u){
    instack[u]=1;
    s.push(u);
    dfn[u]=low[u]=++index;
    int i,x;
    for(i=v[u].size()-1;i>=0;i--){
        x=v[u][i];
        if(!dfn[x]){
            tarjan(x);
            low[u]=min(low[u],low[x]);
        }else if(instack[x]){
            low[u]=min(low[u],dfn[x]);
        }
    }
    if(dfn[u]==low[u]){

        do{
            x=s.top();
            s.pop();
            instack[x]=0;
            id[x]=cnt;
            num[cnt]++;
        }while(x!=u);
        cnt++;
    }
}
int main()
{
    int t,ics=0,m,x,y,i,j;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m
        ics++;
        init();
        for(i=0;i=0;j--){
                x=i;y=v[i][j];
                if(id[x]!=id[y]){
                    in[id[y]]++;
                    out[id[x]]++;
                }
            }
        }
        int ans=0;
        for(i=0;i


你可能感兴趣的:(tarjan)