Taijan算法模板

来源:互联网 发布:12315可以投诉淘宝官方 编辑:程序博客网 时间:2024/06/16 17:09
#include <iostream>#include <string>#include <string.h>#include <algorithm>#include <vector>#define MAXN 10005using namespace std;int dfn[MAXN];int vis[MAXN];int low[MAXN];int belong[MAXN];//属于哪个联通分量 int stack[MAXN];int dfs_num=0,top=0,cnt=0; vector<int> G[MAXN];void Tarjan(int x){    dfn[x] = ++dfs_num;    low[x] = dfs_num;    vis[x] = 1;    stack[++top] = x;    for(int i=0; i<G[x].size(); ++i)    {        int t = G[x][i];        if(!dfn[t])        {            Tarjan(t);            low[x] = min(low[x],low[t]);        }        else if(vis[t])            low[x] = min(low[x],dfn[t]);    }    if(dfn[x] == low[x])    {        cnt++;//联通分量的个数         int j;        do        {            j = stack[top--];            vis[j] = 0;            belong[j] = cnt;        }while(j != x);    }}int main(void){//  freopen("in.txt","r",stdin);    ios::sync_with_stdio(false);    int ncase;    cin >> ncase;    while(ncase--)    {        int n,m;        cin >> n >> m;        int in[n+1],out[n+1];        for(int i=0; i<=n; ++i) G[i].clear();        memset(dfn,0,sizeof(dfn));        memset(vis,0,sizeof(vis));        memset(low,0,sizeof(low));        memset(belong,0,sizeof(belong));        memset(in,0,sizeof(in));        memset(out,0,sizeof(out));        memset(stack,0,sizeof(stack));        dfs_num=0,top=0,cnt=0;        for(int i=0; i<m; ++i)        {            int u,v;            cin >> u >> v;            G[u].push_back(v);        }        for(int i=1; i<=n; ++i)            if(!dfn[i]) Tarjan(i);        if(cnt == 1)//特判         {            cout << '0'<<endl;            continue;        }        //缩点,将每个连通图看成一个点         for(int i=1; i<=n; ++i)        {            for(int j=0; j<G[i].size(); ++j)            {                if(belong[i] != belong[G[i][j]])                {                    in[belong[G[i][j]]]++;                    out[belong[i]]++;                }            }           }           int m1=0,m2=0;        //如果是强联通图,那么每个点至少有一个出度和入度         for(int i=1; i<=cnt; ++i)        {            if(!in[i]) m1++;            if(!out[i]) m2++;        }        cout << max(m1,m2)<<endl;    }    return 0; } 
原创粉丝点击