[POJ 1523] SPF

这是一道求割点的入门题,没什么好讲的,给一组详细的样例数据以供参考:

输入:

1 2

5 4

3 1

3 2

3 4

3 5

0

 

1 2

2 3

3 4

4 5

5 1

0

 

1 2

2 3

3 4

4 6

6 3

2 5

5 1

0

 

1 2

0

 

1000 999

999 998

998 997

997 1000

0

 

1 2

2 3

0

 

1 2

1 3

1 4

1 5

0

 

1 2

1 3

1 4

2 3

2 5

2 6

3 7

3 8

7 8

0

 

1 2

1 3

1 4

1 5

2 3

2 4

2 5

3 4

3 5

4 5

0

 

0


输出:


Network #1
  SPF node 3 leaves 2 subnets


Network #2
  No SPF nodes


Network #3
  SPF node 2 leaves 2 subnets
  SPF node 3 leaves 2 subnets


Network #4
  No SPF nodes


Network #5
  No SPF nodes


Network #6
  SPF node 2 leaves 2 subnets


Network #7
  SPF node 1 leaves 4 subnets


Network #8
  SPF node 1 leaves 2 subnets
  SPF node 2 leaves 3 subnets
  SPF node 3 leaves 2 subnets


Network #9
  No SPF nodes

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <algorithm>
#include <vector>
#define AddEdge(x,y) a.push_back(edge(x,y))
#define MakeSmall(x,y) if(x>y) x=y
#define MaxN 1010
using namespace std;
int head[MaxN],tot;
int low[MaxN],dfn[MaxN],time;
int SubNet[MaxN];
int MinP;
bool CutP[MaxN],v[MaxN];
stack<int> st;
struct edge
{
	int v,next;
	edge(int x,int y):v(y),next(head[x])
	{
		head[x]=tot++;
	}
};
vector<edge> a;
inline void InitGraph()
{
	memset(head,-1,sizeof(head));
	memset(low,0,sizeof(low));
	memset(dfn,0,sizeof(dfn));
	memset(CutP,0,sizeof(CutP));
	memset(v,0,sizeof(v));
	memset(SubNet,0,sizeof(SubNet));
	while(!st.empty()) st.pop();
	time=tot=0,MinP=MaxN;
	a.clear();
}
inline bool init()
{
	InitGraph();
	int x,y;
	scanf("%d",&x);
	if(!x) return 0;
	scanf("%d",&y);
	AddEdge(x,y),AddEdge(y,x);
	MakeSmall(MinP,x);
	MakeSmall(MinP,y);
	for(;;)
	{
		cin>>x;
		if(!x) return 1;
		scanf("%d",&y);
		AddEdge(x,y);
		AddEdge(y,x);
		MakeSmall(MinP,x);
		MakeSmall(MinP,y);
	}
}
void tarjan(int x,int p)
{
	dfn[x]=low[x]=++time;
	int ChNum=0,y;
	st.push(x);
	v[x]=1;
	for(int i=head[x];~i;i=a[i].next)
	{
		y=a[i].v;
		if(p==y) continue;
		if(!dfn[y])
		{
			ChNum++;
			tarjan(y,x);
			low[x]=min(low[x],low[y]);
			if(x!=p&&low[y]>=dfn[x])
			{
				CutP[x]=1;
				SubNet[x]++;
			}
		}
		else if(v[y])
			low[x]=min(low[x],dfn[y]);
	}
	if(dfn[x]==low[x])
	{
		do
		{
			y=st.top();
			st.pop();
			v[x]=0;
		}
		while(x!=y);
	}
	if(x==p&&ChNum>1)
	{
		CutP[x]=1;
		SubNet[x]=ChNum-1;
	}
}
inline void work(int cas)
{
	printf("Network #%d\n",cas);
	tarjan(MinP,MinP);
	bool flag=0;
	for(int i=MinP;i<1001;i++)
		if(CutP[i])
			flag=1,
			printf("  SPF node %d leaves %d subnets\n",i,SubNet[i]+1);
	if(!flag) printf("  No SPF nodes\n");
}
int main()
{
	int CASE=0;
	while(init())
	{
		work(++CASE);
		printf("\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值