图论强连通专题:POJ1236

来源:互联网 发布:社交网络结构挖掘 编辑:程序博客网 时间:2024/06/11 05:19

题目描述:

有一些学校通过单向网络连通,求出下面两个问题:

1.至少在多少个学校拷贝一个软件,使得这个软件能通过网络传遍所有学校。

2.至少加多少条单向网络,使得任意在一个学校拷贝软件,就能使得这个软件通过网络传遍所有学校。

大致思路:

如果直接深搜的话复杂度NM肯定超时,所以先用强连通缩点,然后找出入度为0得点就是第一个问题的答案,而第二个问题就是加多少条边,使得图成为强连通。这个答案就是入度0和出度0点个数中的最大值。

代码:

#include <iostream>#include <vector>#include <cstdio>#include <cstring>using namespace std;const int maxn = 100 + 10;vector<int> G[maxn];vector<int> rG[maxn];int n;vector<int> vs;bool used[maxn];int cmp[maxn];bool g[maxn][maxn];void add_edge(int from, int to) {    G[from].push_back(to);    rG[to].push_back(from);}void dfs(int v) {    used[v] = true;    for (int i = 0; i < G[v].size(); i++) {        if (!used[G[v][i]]) dfs(G[v][i]);    }    vs.push_back(v); } void rdfs(int v, int k) {    used[v] = true;    cmp[v] = k;    for (int i = 0; i < rG[v].size(); i++) {        if (!used[rG[v][i]]) rdfs(rG[v][i], k);    } } int scc() {    memset(used,0,sizeof(used));    vs.clear();    for (int i = 1; i <= n; i++) {        if (!used[i]) dfs(i);    }    memset(used,0,sizeof(used));    int k = 0;    for (int i = vs.size() - 1; i >=0; i--) {        if (!used[vs[i]]) rdfs(vs[i], k++);    }    return k; } int main() {    while (cin>>n) {        for (int i = 1; i <= n; i++) {            int tmp;            while (cin>>tmp,tmp) {                add_edge(i,tmp);            }        }        int nV = scc();        int v_in[maxn],v_out[maxn];        memset(v_in,0,sizeof(v_in));        memset(v_out,0,sizeof(v_out));        memset(g,0,sizeof(g));        for (int i = 1; i <= n; i++) {            for (int j = 0; j < G[i].size(); j++) {                if (cmp[i] != cmp[G[i][j]]) {                    v_in[cmp[G[i][j]]]++;                    v_out[cmp[i]]++;                }            }        }        int zi = 0, zo = 0;        for (int i = 0; i < nV; i++) {            if (!v_in[i]) zi++;            if (!v_out[i]) zo++;        }        if (nV == 1) {            cout<<"1"<<endl<<"0"<<endl;        }        else {            cout<<zi<<endl;            cout<<max(zi,zo)<<endl;        }     } }


0 0