UVA - 796 Critical Links (Tarjan 求圖中的橋)

題目連接

題意:

        1)給你一個圖,然後讓你求圖中橋的個數

        2)要求按字典序輸出

        3)並且要求第一個點的值小於第二個點的值

思路:

        1)Tarjan求橋

        2)要求按字典序輸出,所以可以用set + pair 來儲存

        3)在插入set時比較一下大小再插入。

AC :

#include<iostream>
#include<math.h>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector> 
#include<set>
#define LL long long
#define P pair<int, int>
using namespace std;
const int MAXN = 1e5 + 10;
int head[MAXN], cnt, dfn[MAXN], low[MAXN], tot;
set<P> 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 Tarjan (int x, int fa) {
	low[x] = dfn[x] = ++tot;
	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]);
			if(dfn[x] < low[to]) {	//這條連線是關鍵線 
				ans.insert(make_pair(min(x, to), max(x, to)));
			}
		} else {	//搜過了,改當前的最短時間戳的值 
			low[x] = min(low[x], dfn[to]);	
		} 
	}
}
void init() {
	cnt = 1;
	tot = 0;
	memset(head, 0, sizeof(head));
	memset(dfn, 0, sizeof(dfn));
	memset(low, 0, sizeof(low));
	ans.clear();
}
int main() {
	int n, m;
	while(scanf("%d", &n) != EOF) {
		init();
		int x, y, m;
		for (int i = 1; i <= n; ++i) {
			scanf("%d (%d)", &x, &m);
			for (int i = 1; i <= m; ++i) {
				scanf("%d", &y);
				add_edge(x, y, 0);
				add_edge(y, x, 0);
			}
		}
		for (int i = 0; i < n; ++i) {
			if(!dfn[i])
				Tarjan(i, i);
		}
		int sum = ans.size();
		printf("%d critical links\n", sum);
		for(auto it : ans) {
			printf("%d - %d\n", it.first, it.second);
		} 
		printf("\n");
	}
	return 0;
}

 

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