pku 1523 SPF tarjan算法求割点

http://poj.org/problem?id=1523

求一个无向图的割点,以及输出删除该割点后形成的连通块数(删掉一个割点后会形成两个连通分块)

今天脑子被驴了。晕晕的。。。这样一个模板题整了一上午,各种粗心错误,敲了好几遍,现在看到tarjan就恶心。。。

View Code
#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 1007
using namespace std;
struct node
{
int v;
int next;
}g[maxn*4];
int low[maxn],dfn[maxn],cut[maxn],head[maxn];
int t,index;
int Min = 9999999;
int Max = -9999999;
int root,rtson;
void init()
{
memset(g,0,sizeof(g));
for (int i = 0; i < maxn; ++i)
{
head[i] = cut[i] = low[i] = dfn[i] = 0;
}
t = 1;
index = 0;
}
void add(int u,int v)
{
g[t].v = v;
g[t].next = head[u];
head[u] = t++;
}
void tarjan(int i)
{
int j,k;
low[i] = dfn[i] = ++index;
for (k = head[i]; k; k = g[k].next)
{
j = g[k].v;
if(!dfn[j])
{
tarjan(j);
if (i == root) rtson++;
else
{
if (low[i] > low[j]) low[i] = low[j];
if (low[j] >= dfn[i]) cut[i]++;//这里来记录割点及连通块数
}
}
else if(low[i] > dfn[j])
{
low[i] = dfn[j];
}
}
}
int main()
{
//freopen("d.txt","r",stdin);
int x,y,i,cas = 1;
while (cin>>x)
{
if (!x) break;
cin>>y;
init();
add(x,y); add(y,x);
Min = min(Min,min(x,y));
Max = max(Max,max(x,y));
while (cin>>x)
{
if (!x) break;
cin>>y;
add(x,y); add(y,x);
Min = min(Min,min(x,y));
Max = max(Max,max(x,y));
}
root = Min;
rtson = 0;
tarjan(root);
cut[root] = rtson - 1;
bool flag = false;
printf("Network #%d\n",cas++);
for (i = Min; i <= Max; ++i)
{
if (cut[i] > 0)
{
flag = true;
printf(" SPF node %d leaves %d subnets\n",i,cut[i] + 1);
}
}
if (!flag)
printf(" No SPF nodes\n");
printf("\n");
}
return 0;
}



你可能感兴趣的:(tar)