Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4343 Accepted Submission(s): 1541
#include <bits/stdc++.h>
using namespace std;
const int N = 20005;
const int M = 50005;
struct edge {
int v, next;
edge() {}
edge(int v, int next): v(v), next(next) {}
}e[M], e2[M];
int head[N], head2[N], num[N], in[N], out[N], tot, tot2;
int low[N], dfn[N], Stack[N], belong[N];
int scc, Index, top;
bool Instack[N];
void addedge(int u, int v, bool is) {
if(is) {
e[tot] = edge(v, head[u]);
head[u] = tot++;
}else {
e2[tot2] = edge(v, head2[u]);
head2[u] = tot2++;
}
}
void Tarjan(int u) {
int v;
low[u] = dfn[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u]; ~i; i = e[i].next) {
v = e[i].v;
if(!dfn[v]) {
Tarjan(v);
if(low[u] > low[v]) low[u] = low[v];
}else if(Instack[v] && low[u] > dfn[v]) {
low[u] = dfn[v];
}
}
if(low[u] == dfn[u])
{
scc++;
do {
v = Stack[--top];
Instack[v] = false;
belong[v] = scc;
num[scc]++;
} while(v != u);
}
}
void solve(int n)
{
memset(dfn, 0, sizeof dfn);
memset(Instack, false, sizeof Instack);
memset(num, 0, sizeof num);
Index = scc = top = 0;
for(int i = 1; i <= n; ++i) if(!dfn[i]) Tarjan(i);
}
void init() {
tot = tot2 = 0;
memset(head, -1, sizeof head);
memset(head2, -1, sizeof head2);
}
int main()
{
int _; scanf("%d", &_);
while(_ --)
{
init();
int n, m, u, v;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m ;++i) {
scanf("%d%d", &u, &v);
addedge(u, v, true);
}
solve(n);
memset(in, 0, sizeof in);
memset(out, 0, sizeof out);
for(int u = 1; u <= n; ++u) {
for(int i = head[u]; ~i; i = e[i].next) {
int v = e[i].v;
if(belong[u] != belong[v]) {
addedge(belong[u], belong[v], false);
}
}
}
for(int u = 1; u <= scc; ++u) {
for(int i = head2[u]; ~i; i = e2[i].next) {
int v = e2[i].v;
in[v]++;
out[u]++;
}
}
int a = 0, b = 0;
for(int i = 1; i <= scc; ++i) {
if(in[i] == 0) a++;
if(out[i] == 0) b++;
}
printf("%d\n", scc == 1 ? 0 : max(a, b));
}
return 0;
}
hdu2767 Proving Equivalences有向图的强连通_Tarjan缩点
原文:http://www.cnblogs.com/orchidzjl/p/4901689.html