大致思路:
第一个小问是问在多少电脑上放置源文件,能传遍整个计算机网络,答案很明显就是强连通缩点之后入度为0的点的个数。
第二个小问是问加多少边之后,在任意一个电脑上放置源文件,就能传遍整个计算机网络,这个问题就是要把缩点之后的图变成一个强连通分量,也就是说要消灭入度为0和出度为0的点,所以答案就是max(入度=0的点,出度=0的点)。
代码:
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define IT iterator
#define PB(x) push_back(x)
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef vector<ull> vull;
typedef set<int> sint;
typedef set<ull> sull;
const int maxn = 10000 + 5;
vint G[maxn];
int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
stack<int> S;
int a[maxn];
void init(int n) {
for (int i = 0; i <= n; i++) G[i].clear();
}
void dfs(int u) {
pre[u] = lowlink[u] = ++dfs_clock;
S.push(u);
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i];
if (!pre[v]) {
dfs(v);
lowlink[u] = min(lowlink[u],lowlink[v]);
}
else if (!sccno[v]) {
lowlink[u] = min(lowlink[u],pre[v]);
}
}
if (lowlink[u] == pre[u]) {
scc_cnt++;
while (1) {
int x = S.top();
S.pop();
sccno[x] = scc_cnt;
if (x == u) break;
}
}
}
void find_scc(int n) {
dfs_clock = scc_cnt = 0;
CLR(sccno,0);
CLR(pre,0);
for (int i = 1; i <= n; i++) {
if (!pre[i]) dfs(i);
}
}
int in[maxn];
int out[maxn];
int main() {
int n,m;
//freopen("data.in","r",stdin);
while (cin>>n) {
init(n);
for (int i = 1; i <= n; i++) {
int m;
while (scanf("%d",&m),m) {
G[i].PB(m);
}
}
//for (int i = 0; i <= scc_cnt; i++) new_g[i].clear();
find_scc(n);
CLR(in,0);
CLR(out,0);
int tmpa = 0,tmpb = 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < G[i].size(); j++) {
int v = G[i][j];
if (sccno[i] != sccno[v]) {
out[sccno[i]]++;
in[sccno[v]]++;
}
}
}
for (int i = 1; i <= scc_cnt; i++) {
if (!out[i]) tmpb++;
if (!in[i]) tmpa++;
}
cout<<tmpa<<endl<<(scc_cnt == 1 ? 0 : max(tmpb,tmpa))<<endl;
}
}