您的位置:首页 > 其它

POJ_1236 Network of School (Tarjan)

2012-02-11 14:59 253 查看
  Tarjan 它好贱,wa了10+次。。。

  思路:用“它贱”进行强连通缩点。然后统计缩点后的图中入度为0的点的个数in和出度为0的点到个数out。A就是in, B就是max(in, out);

渣代码:

View Code

#include <iostream>
#include <cstring>
#include <cstdio>
#include <stack>

using namespace std;

const int N = 110;

struct node {
int to;
int next;
} g[N*N/2];

int head
, blong
;
int dfn
, low
;
int in
, out
;
int t, cnt, ind;
bool vis
;

stack<int> s;

void init() {
memset(g, 0, sizeof(g));
memset(head, 0, sizeof(head));
memset(blong, 0, sizeof(blong));
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(vis, 0, sizeof(vis));
t = 1; cnt = ind = 0;
}

void add(int u, int v) {
g[t].to = v; g[t].next = head[u]; head[u] = t++;
}

void tarjan(int u) {
int v, i;
vis[u] = true;
s.push(u);
low[u] = dfn[u] = ++ind;
for(i = head[u]; i; i = g[i].next) {
v = g[i].to;
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if(vis[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u]) {
cnt++;
do {
v = s.top();
s.pop();
//printf("%d %d\n", v, cnt);
blong[v] = cnt;
vis[v] = false;
} while(v != u);
}
}

int main() {
//freopen("data.in","r", stdin);

int i, j, v, a, b, n;
while(~scanf("%d", &n)) {
init();
for(i = 1; i <= n; i++) {
while(scanf("%d", &v), v) {
add(i, v);
}
}

for(i = 1; i <= n; i++) {
if(!dfn[i])    tarjan(i);
}

for(i = 1; i <= n; i++) {
for(j = head[i]; j; j = g[j].next) {
v = g[j].to;
if(blong[i] != blong[v]) {
in[blong[v]]++; out[blong[i]]++;
}
}
}
a = b = 0;
for(i = 1; i <= cnt; i++) {
if(!in[i])    a++;
if(!out[i])    b++;
}
printf("%d\n", a);
if(cnt == 1)    printf("0\n");
else    printf("%d\n", max(a, b));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: