程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 3313 Key Vertex(dfs + bfs)

HDU 3313 Key Vertex(dfs + bfs)

編輯:C++入門知識

HDU 3313 Key Vertex(dfs + bfs)


HDU 3313 Key Vertex

題目鏈接

題意:一個有向無環圖,求s,t之間的割點

思路:先spfa找一條最短路出來,如果不存在,就n個都是割點。
然後每次從s進行dfs,找到能經過最短路上的最遠點,然後這個點就是割點,然後下次在以這個為起點dfs,不斷迭代直到找到t為止

代碼:

#include 
#include 
#include 
#include 
#include 
using namespace std;

const int N = 100005;

int n, m, s, t, fa[N], vis[N], mark[N], d[N];
int first[N], vv[N * 3], next[N * 3], en;

const int INF = 0x3f3f3f3f;

void addedge(int a, int b) {
	vv[en] = b;
	next[en] = first[a];
	first[a] = en++;
}

bool bfs() {
	queue Q;
	for (int i = 0; i < n; i++) d[i] = INF;
	memset(vis, 0, sizeof(vis));
	Q.push(s);
	vis[s] = 1;
	d[s] = 0;
	while (!Q.empty()) {
		int u = Q.front();
		vis[u] = 0;
		Q.pop();
		for (int i = first[u]; i + 1; i = next[i]) {
			int v = vv[i];
			if (d[v] > d[u] + 1) {
				d[v] = d[u] + 1;
				fa[v] = u;
				if (!vis[v]) {
					Q.push(v);
					vis[v] = 1;
				}
			}
		}
	}
	if (d[t] >= INF) return false;
	int tmp = t;
	memset(mark, 0, sizeof(mark));
	while (tmp != s) {
		mark[tmp] = 1;
		tmp = fa[tmp];
	}
	mark[s] = mark[t] = 1;
	return true;
}

void dfs(int u) {
	for (int i = first[u]; i + 1; i = next[i]) {
		int v = vv[i];
		if (vis[v]) continue;
		vis[v] = 1;
		if (mark[v]) {
			if (d[v] > d[s])
				s = v;
			continue;
		}
		dfs(v);
	}
}

int main() {
	while (~scanf("%d%d", &n, &m)) {
		memset(first, -1, sizeof(first));
		en = 0;
		int u, v;
		while (m--) {
			scanf("%d%d", &u, &v);
			addedge(u, v);
		}
		scanf("%d%d", &s, &t);
		if (!bfs()) {
			printf("%d\n", n);
			continue;
		}
		int ans = 1;
		memset(vis, 0, sizeof(vis));
		while (s != t) {
			dfs(s);
			ans++;
		}
		printf("%d\n", ans);
	}
	return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved