Tarjan
第一个问题:问不加边时,有向图的连通分量 第二个问题:最少加多少条边才能让有向图成为一个强连通图。第一个问题略。
对于无向图,在缩点之后,图会成一个无向树,最少需要加 (叶结点+1)/2 条边就能让无向图成为一个双连通图。
有向图则是,在缩点之后,最少加 max(入度为0的个数,出度为0的个数) 条边就能让有向图成为一个强连通图。
这里解释一下这个结论。
无向图缩点之后,整个图是一个无向树,如果原图不连通的话,则是一个森林。和无向图一样,有向图缩点之后,整个图也是一个森林,只不过是有向的。
要想让图成为一个强连通图,就需要把森林里的每一棵树连起来,成为强连通图最省边的方法是,一个森林的叶结点去连另一颗树的根节点。
假设现在有 3 棵树,第一棵树的叶结点去连第二棵树的根节点,第二棵树的叶结点去连第三棵树的根节点,第三棵树的叶结点去连第一棵树的根节点。
以这种方式去连边是最省的,所以得出 max(入度为0的个数,出度为0的个数) 这个结论。
另外需要注意,如果scc == 1,出入度为0的点的个数都是1,但是答案应该是0,这个需要特判。
#pragma GCC optimize(2)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
const int Maxn = 100+10;
const int INF = 0x3f3f3f3f;
const int Mod = 1e9+7;
vector <int> G[Maxn];
int dfn[Maxn], low[Maxn], scc, num[Maxn];
int Stack[Maxn], Top, indx, indeg[Maxn], outdeg[Maxn];
bool instack[Maxn];
void Tarjan(int u) {
dfn[u] = low[u] = ++indx;
Stack[Top++] = u;
instack[u] = true;
int len = G[u].size();
for(int i = 0; i < len; ++i) {
int v = G[u][i];
if(!dfn[v]) {
Tarjan(v);
low[u] = min(low[u], low[v]);
} else if(instack[v]) low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u]) {
scc++;
int v;
do {
v = Stack[--Top];
instack[v] = false;
num[v] = scc;
} while(u != v);
}
}
int main(void)
{
int n;
scanf("%d", &n);
int v;
for(int u = 1; u <= n; ++u) {
while(1) {
scanf("%d", &v);
if(v == 0) break;
G[u].push_back(v);
}
}
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(instack, false, sizeof(instack));
scc = Top = indx = 0;
for(int i = 1; i <= n; ++i) if(!dfn[i]) Tarjan(i);
memset(indeg, 0, sizeof(indeg));
memset(outdeg, 0, sizeof(outdeg));
for(int i = 1; i <= n; ++i) {
int len = G[i].size();
for(int j = 0; j < len; ++j) {
v = G[i][j];
if(num[i] != num[v]) {
outdeg[num[i]]++;
indeg[num[v]]++;
}
}
}
int ans_1 = 0, ans_2 = 0;
for(int i = 1; i <= scc; ++i) {
if(indeg[i] == 0) ans_1++;
else if(outdeg[i] == 0) ans_2++;
}
printf("%d\n%d\n", ans_1, (scc == 1) ? 0 : max(ans_1, ans_2));
return 0;
}
浙公网安备 33010602011771号