码迷,mamicode.com
首页 > 其他好文 > 详细

UvaLive 4287 Proving Equivalences 强连通缩点

时间:2015-09-08 20:10:43      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

原题链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2288

题意:

给你一个有向图,问你至少需要添加多少条边,使得整个图强连通。

题解:

就。。直接缩点,令缩点后入度为0的点有a个,出度为0的点有b个,答案就是max(a,b)

代码:

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<stack>
#define MAX_N 20004
using namespace std;

vector<int> G[MAX_N];
int dfn[MAX_N],low[MAX_N],ind;
bool vis[MAX_N];
stack<int> st;
bool inStack[MAX_N];

int id[MAX_N],tot=0;
vector<int> newG[MAX_N];
vector<int> newrG[MAX_N];

int n,m;

void init() {
    for (int i = 0; i <= n; i++) {
        G[i].clear();
        newG[i].clear();
        newrG[i].clear();
    }
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    ind = tot = 0;
    memset(vis, 0, sizeof(vis));
    while (st.size())st.pop();
    memset(inStack, 0, sizeof(inStack));
    memset(id, 0, sizeof(id));
}

void Tarjan(int u) {
    dfn[u] = low[u] = ++ind;
    st.push(u);
    inStack[u] = 1;
    vis[u] = 1;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (!vis[v]) {
            Tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if (inStack[v])
            low[u] = min(low[u], dfn[v]);
    }
    if (low[u] == dfn[u]) {
        tot++;
        int t;
        do {
            t = st.top();
            st.pop();
            inStack[t] = 0;
            id[t] = tot;
        } while (t != u);
    }
}

int main() {
    int T;
    cin.sync_with_stdio(false);
    cin >> T;
    while (T--) {
        cin >> n >> m;
        int ans = 0;
        init();
        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 (!vis[i])Tarjan(i);
        for (int u = 1; u <= n; u++)
            for (int i = 0; i < G[u].size(); i++)
                if (id[u] != id[G[u][i]]) {
                    newG[id[u]].push_back(id[G[u][i]]);
                    newrG[id[G[u][i]]].push_back(id[u]);
                }
        if (tot == 1) {
            cout << 0 << endl;
            continue;
        }
        int a = 0, b = 0;
        for (int u = 1; u <= tot; u++) {
            if (newG[u].size() == 0)a++;
            if (newrG[u].size() == 0)b++;
        }
        cout << max(a, b) << endl;
    }
    return 0;
}

 

UvaLive 4287 Proving Equivalences 强连通缩点

标签:

原文地址:http://www.cnblogs.com/HarryGuo2012/p/4792659.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!