【POJ - 1523】SPF(Tarjan求割点,求分割成的连通块数,模板题,tricks)

题干:

Consider the two networks shown below. Assuming that data moves around these networks only between directly connected nodes on a peer-to-peer basis, a failure of a single node, 3, in the network on the left would prevent some of the still available nodes from communicating with each other. Nodes 1 and 2 could still communicate with each other as could nodes 4 and 5, but communication between any other pairs of nodes would no longer be possible. 

Node 3 is therefore a Single Point of Failure (SPF) for this network. Strictly, an SPF will be defined as any node that, if unavailable, would prevent at least one pair of available nodes from being able to communicate on what was previously a fully connected network. Note that the network on the right has no such node; there is no SPF in the network. At least two machines must fail before there are any pairs of available nodes which cannot communicate. 

Input

The input will contain the description of several networks. A network description will consist of pairs of integers, one pair per line, that identify connected nodes. Ordering of the pairs is irrelevant; 1 2 and 2 1 specify the same connection. All node numbers will range from 1 to 1000. A line containing a single zero ends the list of connected nodes. An empty network description flags the end of the input. Blank lines in the input file should be ignored.

Output

For each network in the input, you will output its number in the file, followed by a list of any SPF nodes that exist. 

The first network in the file should be identified as "Network #1", the second as "Network #2", etc. For each SPF node, output a line, formatted as shown in the examples below, that identifies the node and the number of fully connected subnets that remain when that node fails. If the network has no SPF nodes, simply output the text "No SPF nodes" instead of a list of SPF nodes.

Sample Input

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

0

Sample Output

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

题目大意:

给你一个联通网路(应该是无自环无回路的),求出这个网络所有割点的编号,以及如果删除这个割点之后所对应的联通分量数。

解题报告:

  就是个板子题,,就是输出格式比较坑。。

  再就是注意几个地方,一个是if(dfn[x]==0)的时候的low[x]别忘更新,第二是son++要在if(dfn[x]==0)这个判断内。(不然的话就算下面的if(x == rt && son > 1)改成son>2也不行。)

再就是一开始写的时候把init函数放到n=max(a,b)后面了,这样肯定不对啊你都add了两条边了然后又给人家清空了,,还好样例比较良心直接就能发现,不然这个小错又得找半天错。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
struct Edge {
	int u,v;
	int ne;
} e[MAX];
int dfn[MAX],low[MAX],clk;
int head[MAX],tot;
int gd[MAX];
int n;
void init() {
	for(int i = 1; i<=1000; i++) {
		dfn[i]=low[i]=gd[i]=0;
		head[i] = -1;
	}
	tot = 0;
	clk = 0;
}
void add(int u,int v) {
	e[++tot].u = u;e[tot].v = v;
	e[tot].ne = head[u];head[u] = tot;
}
void tarjan(int x,int fa,int rt) {//注意这里fa和rt是不一样的含义!! 
	dfn[x] = low[x] = ++clk;
	int son = 0;
	for(int i = head[x]; ~i; i = e[i].ne) {
		int v = e[i].v;
		if(v == fa) continue;
		if(dfn[v] == 0) {
			son++;//放到dfn[v]==0这个if外面也可以??这两种都可以?? 答:不可以 
			tarjan(v,x,rt);
			low[x] = min(low[x],low[v]);//别忘这一步啊傻不傻、、
			if(x != rt && low[v] >= dfn[x]) {
				gd[x]++;
			}
		}
		else low[x] = min(low[x],dfn[v]);
	}
	if(x == rt && son > 1) {
		gd[x] = son-1;
	}
}
int main()
{
	int a,b,iCase=0;
	
	while(~scanf("%d",&a) && a) {
		scanf("%d",&b);
		init();
		add(a,b);add(b,a);
		n=max(a,b); 
		while(~scanf("%d",&a) && a) {
			scanf("%d",&b);
			add(a,b);add(b,a);
			n=max(n,a);n=max(n,b);
		}
		tarjan(1,-1,1);
		printf("Network #%d\n",++iCase);
		int flag = 0;
		for(int i = 1; i<=n; i++) {
			if(gd[i] != 0) printf("  SPF node %d leaves %d subnets\n",i,gd[i]+1),flag = 1;
		}
		if(flag == 0) printf("  No SPF nodes\n");
		printf("\n");
	}


	return 0 ;
}
全部评论

相关推荐

1.第一种人呢以92和计算机强双非(四邮四电)偏多,这种人呢,喜欢把自己的学校称为“大专”,极力在交流时贬低自己的学历,放大自己学历的缺点(如牛客经典贴,双非秋招oc美团,点开发现是985硕士🤣🤣🤣),说的自己学校好像比双非认可度还低,好像这样才能突出自己多么牛逼,克服了多少困难,技术有多强,但你要是说想双非考研去他们学校,他们又要狠狠打压你,告诉考他们学校多难了🤣🤣🤣。从92到大厂明明是证明自己一直优秀的一条路,你不走,你非要故意恶心自己也恶心别人,何必呢?2.第二种人以像我一样的双非同学偏多,大多学历比较低,可能又带有中大厂实习。他们会在你交流的时候,十分刻意的强调自己是弱双非或者学院本,再不经意透露自己在某某大厂实习。等着群聊里响起“原来是xx(大厂名字)✌🏻啊,给你跪了😭”,他们便心满意足了。不用反驳,因为我之前也是这种人,现在也有这种倾向😆😆😆。3.第三种人更是神人,跟这种人交流时,你会觉得对方已经被美国植入芯片控制了,张嘴闭嘴只有膜膜膜,羡慕羡慕羡慕。上到拿到大厂offer,下到喝一杯奶茶,他们都说羡慕。不知道他们的生活过得有多么悲惨,连喝杯饮料都到了羡慕的地步🤣🤣🤣。天天就是在群里面互相吹捧,互相羡慕,不知道交流起来有什么意思。4.第四种人则是第一种人的对立面,我有时候觉得是第四种人太多才会导致第一种人的出现。这种人天生带着对92的恨。仿佛学计算机没有拿到offer全是92导致的。他们是小说里被陷害的白莲花女主,92则是夺走他们人生的恶毒女配。在他们的眼中,他们的技术要比92好一百倍,但是所有企业都识别不了他们这匹千里马。实际自己从来没想过,在ai与辅导课程普及的当日,所谓的计算机,早已经没有了任何的技术壁垒,否则也不会有那么人转码了😂。这是那天回家路上发抖音的,讨论不少,有赞同有不赞同的,其实有时候也在想自己言论是否偏激。今天遇到朋友问我好久没更新牛客了,就搬了上去。其实很简单,加了交流群之后,发现交流的质量参差不齐,有些实在言之无物,想了想自己也会有这样的问题。自己也在建交流群,希望能避免这样的现象吧
wu970:交流群不就是一群人互相装逼和加装谦虚吗
如何排解工作中的焦虑
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务