用tarjan缩点重建图

来源:互联网 发布:手机看车用什么软件 编辑:程序博客网 时间:2024/05/19 14:02

尝试一下缩点减新图。代码应当是poj2186的,但是poj崩了,也不知代码对不对。。。

#include<iostream>#include<string>#include<stack>#include<vector>using namespace std;#define mem(arr,a) memset(arr,a,sizeof(arr))#define N 10000#define MAXN 50000vector<int>G[N];//原图vector<int>rG[N];//重建的图vector<int>tG[N];//用来保存新图每个节点对应的连通分量里的点int dfn[N], low[N], vis[N];int n, m;int cnt,counts;int id[N];//连通分量里的点对应新图点的编号void add(int a, int b){    G[a].push_back(b);}void tarjan(int u){    stack<int>s;    dfn[u] = low[u] = ++cnt;    vis[u] = 1;    s.push(u);    for (int i = 0; i < G[u].size(); i++){        int v = G[u][i];        if (!dfn[v]){            tarjan(v);            if (low[v] < low[u])low[u] = low[v];        }        else if (vis[v] && low[u]>dfn[v])low[u] = dfn[v];    }    while (!s.empty()){        int t = s.top();        s.pop();        id[t] = counts;        tG[counts].push_back(t);        if (t == u)break;    }    counts++;}void Tarjan(){    for (int i = 1; i <= n; i++){        if (!dfn[i])tarjan(i);    }}int main(){    cin >> n >> m;    while (m--){        int a, b; cin >> a >> b; add(a, b);    }    Tarjan();    mem(vis, 0);    for (int i = 0; i < counts; i++){        vis[i] = 0;        for (int j = 0; j < tG[i].size(); j++){            int u = tG[i][j];            for (int k = 0; k < G[u].size(); k++){                if (!vis[id[G[u][k]]]){                    vis[id[G[u][k]]] = 1;                    rG[i].push_back(id[G[u][k]]);                }            }        }    }    int t = 0, flag = 0;    for (int i = 0; i < counts; i++){        if (rG[i].size() == 0){            flag++;            t = i;        }    }    if (flag == 1)cout << tG[t].size() << endl;    else cout << 0 << endl;}