Network(无向图割点,tarjan)

1. 割点含义

在一个无向图中,如果有一个顶点,删除这个顶点及其相关联的边后,图的连通分量增多,就称该点是割点,该点构成的集合就是割点集合。简单来说就是去掉该点后其所在的连通图不再连通,则该点称为割点。
若去掉某条边后,该图不再连通,则该边称为桥或割边。

若在图G中(如下图),删除uv这条边后,图的连通分量增多,则u和v点称为割点,uv这条边称为桥或割边。
在这里插入图片描述

2. 题意

A Telephone Line Company (TLC) is establishing a new telephone cable network. They are connecting
several places numbered by integers from 1 to N. No two places have the same number. The lines
are bidirectional and always connect together two places and in each place the lines end in a telephone
exchange. There is one telephone exchange in each place. From each place it is possible to reach
through lines every other place, however it need not be a direct connection, it can go through several
exchanges. From time to time the power supply fails at a place and then the exchange does not operate.
The officials from TLC realized that in such a case it can happen that besides the fact that the place
with the failure is unreachable, this can also cause that some other places cannot connect to each other.
In such a case we will say the place (where the failure occured) is critical. Now the officials are trying
to write a program for finding the number of all such critical places. Help them.

一个电话信号传输公司正在搭建一个新的电话电缆网络。他们想要连接从1到N标号的各个地点,标号不重复。电缆是双向作用的,在每个地方电缆都链接一个信号站。每个地点都有一个信号站。信号站与信号站之间可能通过若干个信号站实现连通。有的时候一个地点断电了那么部分信号站便都收不到信号。信号传输公司意识到这是因为一个地方信号站的失效而导致的其他地方信号站的失效,这样的信号站被称为中转站。现在信号传输公司想找出有多少个这样的中转站,请帮助他们。

2.1 输入

Input
The input file consists of several blocks of lines. Each block describes one network. In the first line
of each block there is the number of places N < 100. Each of the next at most N lines contains the
number of a place followed by the numbers of some places to which there is a direct line from this place.
These at most N lines completely describe the network, i.e., each direct connection of two places in
the network is contained at least in one row. All numbers in one line are separated by one space. Each
block ends with a line containing just ‘0’. The last block has only one line with N = 0.

多样例输入,每个样例包括一个网络
第一行输入N(N<100),接下来的最多N行,每行第一个数表示一个地点,接下来的若干个数表示与改点连接有电缆的地点,当第一个数输入为0时,该样例输入结束。
当N为0 时,输入结束。

2.2 输出

Output
The output contains for each block except the last in the input file one line containing the number of
critical places.

对于每个样例输出中转站的个数。

3.题解

就是用tarjan求割点,不过需要注意一下输入。

4.代码

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
const int N=110,M=2e4+5;
struct E
{
	int to,next;
} e[M];
int n,u,v,len,root,h[N],num,dfn[N],low[N];
char c;
bool cut[N];
void init()
{
	memset(h,0,sizeof(h));
	memset(dfn,0,sizeof(dfn));
	memset(cut,false,sizeof(cut));
}
void add(int u,int v)
{
	e[++len].to=v;
	e[len].next=h[u];
	h[u]=len;
}
//tarjan模板
void tarjan(int u)
{
	dfn[u]=low[u]=++num;
	int cnt=0;
	int i,j;
	for(j=h[u]; j; j=e[j].next)
	{
		int v=e[j].to;
		if(!dfn[v])
		{
			tarjan(v);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u])
			{
				cnt++;
				if(u!=root||cnt>1)
					cut[u]=true;
			}
		}
		else
			low[u]=min(low[u],dfn[v]);
	}
}
int main()
{
	int i,j;
	while(~scanf("%d",&n)&&n)
	{
		init();
		len=0,num=0;
		//注意本题的输入问题
		//输入完每一行的第一个数之后,后面的数不知道有多少
		//直到跳到第二行之后,上一行才输入结束。
		//所以用循环,用一个字符输入,字符输入碰到空格结束,就输入数字
		//直到字符碰到换行就停止该行的输入
		while(~scanf("%d",&u)&&u)
		{
			while(~scanf("%c",&c)&&c!='\n')
			{
				scanf("%d",&v);
				add(u,v);
				add(v,u);
			}
		}
		for(root=1; root<=n; root++)
		{
			if(!dfn[root])//当前的root还没有被访问过
				tarjan(root);
		}
		int ans=0;
		for(i=1; i<=n; i++)
			if(cut[i])
				ans++;
		printf("%d\n",ans);
	}
	return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值