POJ1144 Network(Tarjan求割點)

題目連接

題意:

        讓求一個圖中的關鍵節點(割點),輸入稍微有點麻煩,不給你一個點有幾個邊,直接輸入邊,讀到換行才結束。

思路:

        1)Tarjan求一下改圖割點的數量。

        2)注意輸入讀到換行才停止,用getchar()。點擊補習讀入方式

AC代碼


/*
Tarjan 割點 
//如果這個點時根節點,並且兒子>=2則這個點就是割點 
//對於點U存在子節點V,V可以訪問到U的父節點,那麼點U就不是割點,否則就是割點
*/ 
#include<iostream>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<stdio.h>
#include<stack>
#include<set>
using namespace std;
const int MAXN = 1e5;
int head[MAXN], cnt, tot, dfn[MAXN], low[MAXN];
int root; 
int n, m;
set<int> ans;
struct Edge{
	int to, dis, next;
}edge[MAXN << 1];
void add_edge(int u, int v, int dis) {
	edge[++cnt].to = v;
	edge[cnt].dis = dis;
	edge[cnt].next = head[u];
	head[u] = cnt;
}
void init() {
	cnt = 1;
	tot = 0;
	memset(head, 0, sizeof(head));
	memset(dfn, 0, sizeof(dfn));
	memset(low, 0, sizeof(low));
	ans.clear();
}
void Tarjan(int x, int fa) {
	low[x] = dfn[x] = ++tot;
	int son = 0;
	for (int i = head[x]; i; i = edge[i].next) {
		int to = edge[i].to;
		if(to == fa) continue;	//因爲是無向圖所以把回邊給跳過了 
		if (!dfn[to]) {
			Tarjan(to, x);
			low[x] = min(low[x], low[to]); 
			son++;
			if ( x == root && son > 1) {	//如果這個點時根節點,並且兒子>=2則這個點就是割點 
				ans.insert(x);
			} else if (x != root && dfn[x] <= low[to] ) { //對於點U存在子節點V,V可以訪問到U的父節點,那麼點U就不是割點,否則就是割點
				ans.insert(x);
			}
		} else {
			low[x] = min(low[x], dfn[to]); 
		}
	}
}
int main() {
	while(scanf("%d", &n) == 1 && n) {
		int u, v;
		init(); 
		while(scanf("%d", &u) == 1 && u) {
			while(getchar()!='\n'){
				scanf("%d", &v);	
				add_edge(u, v, 0);
				add_edge(v, u, 0); 
			}
		}
		for (int i = 1; i <= n; ++i) {
			if (!dfn[i]){
				root = i;
				Tarjan(i, i);
			}
		}
		printf("%d\n", ans.size());
	}
	return 0;
} 

 

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