您的位置:首页 > 其它

POJ-1523 SPF 无向图求割点

2012-08-20 11:18 513 查看
简单的无向图求割点.

代码如下:

#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define MAXN 1005
using namespace std;

int head[MAXN], idx, LIM, dfn[MAXN], low[MAXN], ti;
int subnet[MAXN];
bool vis[MAXN];

struct Edge
{
int v, next;
}e[MAXN*MAXN];

void AddEdge(int x, int v)
{
++idx;
e[idx].v = v, e[idx].next = head[x];
head[x] = idx;
}

void dfs(int u)
{ // low 值一定是越低越好
for (int i = head[u]; i != -1; i = e[i].next) {
if (!vis[e[i].v]) {
vis[e[i].v] = true;
dfn[e[i].v] = low[e[i].v] = ++ti;
dfs(e[i].v);
low[u] = min(low[u], low[e[i].v]);
if (low[e[i].v] == dfn[u]) { // 孩子中不存在抵达上层的其他途径
++subnet[u];
}
}
else {
low[u] = min(low[u], dfn[e[i].v]);
}
}
}

void solve()
{
bool flag = false;
memset(vis, false, sizeof (vis));
memset(subnet, 0, sizeof (subnet));
subnet[1] = -1;
vis[1] = true; // 由于图一定是联通的,所以就一定能够找到所有的点
dfn[1] = low[1] = ++ti;
dfs(1);
for (int i = 1; i <= LIM; ++i) {
if (subnet[i] > 0) {
printf("  SPF node %d leaves %d subnets\n", i, subnet[i]+1);
flag = 1;
}
}
if (!flag) {
puts("  No SPF nodes");
}
}

int main()
{
int a, b, ca = 0;
bool indata = false, first = true;
LIM = ti = 0, idx = -1;
memset(head, 0xff, sizeof (head));
while (1) {
scanf("%d", &a);
LIM = max(LIM, a);
if (!a) {
if (!indata) break;
else {
if (first) {
first = false;
}
else {
puts("");
}
indata = false;
printf("Network #%d\n", ++ca);
solve();
LIM = ti = 0, idx = -1; // 一个初始化
memset(head, 0xff, sizeof (head));
continue;
}
}
indata = true;
scanf("%d", &b);  // 表示a,b之间有一条无向边
LIM = max(LIM, b); // 找到最大的顶点编号
AddEdge(a, b);
AddEdge(b, a);  // 无向图的双向边
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: