POJ1523——割點+連通分量

題目鏈接:

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

請考慮如下所示的兩個網絡。假設數據僅在直接連接的節點之間在對等基礎上在這些網絡之間移動,則左側網絡中單個節點 3 的故障將阻止某些仍然可用的節點相互通信。節點 1 和節點 2 仍可以像節點 4 和 5 那樣相互通信,但任何其他節點對之間的通信將不再可能。‎
‎因此,節點 3 是此網絡的單點故障點 (SPF)。 ‎
‎嚴格來說,SPF 將定義爲任何節點,如果不可用,將阻止至少一對可用節點在以前完全連接的網絡上進行通信。請注意,右側的網絡沒有此類節點;網絡中沒有 SPF。在有任何一對可用節點無法通信之前,必須至少兩臺計算機發生故障。‎

‎輸入‎

‎輸入將包含多個網絡的說明。網絡描述將由一對整數(每行一對)組成,用於標識連接的節點。對的順序是無關緊要的;1 2 和 2 1 指定相同的連接。所有節點編號的範圍爲 1 到 1000。包含單個零的行將結束連接節點的列表。空網絡描述標記輸入的末尾。應忽略輸入文件中的空白行。‎

‎輸出‎

‎對於輸入中的每個網絡,您將在文件中輸出其編號,後跟存在的任何 SPF 節點的列表。‎
‎文件中的第一個網絡應標識爲"網絡#1",第二個網絡應標識爲"網絡#2"‎
‎等。對於每個 SPF 節點,輸出一行,格式如下示例所示,用於標識該節點和節點發生故障時保留的完全連接的子網數。如果網絡沒有 SPF 節點,只需輸出文本"無 SPF 節點",而不是 SPF 節點列表。

 

題意很簡單,就是讓你求圖中的割點個數有多少,之後再去求去掉割點後的連通分量的個數。

關於割點的求法不懂的可以看這篇文章:https://blog.csdn.net/wtyvhreal/article/details/43530613

求完割點後,再對每一個割點開始求DFS,利用劉汝佳白書裏面的內容就可以求出連通分量的個數了。

an#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e3+7;
int low[maxn],dfn[maxn];
int visited[maxn];
int cut[maxn];
int head[maxn];
int n,num,kase,cnt,root,root_son,t;
struct Edge{
	int to,nxt;
}edge[maxn*100];
void init(){
	memset(head,-1,sizeof(head));
	memset(low,0,sizeof(low));
	memset(visited,0,sizeof(visited));
	memset(cut,0,sizeof(cut));
	memset(dfn,0,sizeof dfn);
	cnt=0;
	kase++;
	num=1;
	n=-1; 
}
void addedge(int from,int to){
	edge[cnt].to=to;
	edge[cnt].nxt=head[from];
	head[from]=cnt++;
}
void tarjan(int u){
	low[u]=dfn[u]=num++;
	for(int i = head[u];~i;i=edge[i].nxt){
		int v=edge[i].to;
		if(!dfn[v]){
			tarjan(v);
			if(u==root) root_son++;
			else {
				low[u]=min(low[u],low[v]);
				if(low[v]>=dfn[u]) cut[u]=1;
			}
		}
		else if(low[u]>dfn[v]) low[u]=dfn[v];
	}
}
void dfs(int u){
	visited[u]=1;
	for(int i = head[u];~i;i=edge[i].nxt){
		int v=edge[i].to;
		if(!visited[v]){
			visited[v]=1;
			dfs(v);
		}
	}
}
int main(int argc, char** argv) {
	kase=0;
	int u,v;
	while(~scanf("%d",&u)&&u){
		init();
		n=max(n,u);
		scanf("%d",&v);
		n=max(n,v);
		addedge(u,v);
		addedge(v,u);
		while(scanf("%d",&u)&&u){
			n=max(n,u);
			scanf("%d",&v);
			n=max(n,v);
			addedge(u,v);
			addedge(v,u);
		}
		root=1;
		root_son=0;
		tarjan(root);
		if(root_son>=2){
			cut[root]=1;
		}
		printf("Network #%d\n",kase);
		int flag=0;
		for(int u = 1;u<=n;++u){
			if(cut[u]){
				flag=1;
				memset(visited,0,sizeof(visited));
				visited[u]=1;
				int son=0;
				for(int i = head[u];~i;i=edge[i].nxt){
					int v=edge[i].to;
					if(!visited[v]){
						dfs(v);
						son++;
					}
				}
				printf("  SPF node %d leaves %d subnets\n",u,son);
			}
		}
		if(!flag) printf("  No SPF nodes\n");
		printf("\n");
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章