标签:style blog http io color ar os sp for
题意:一个有向无环图,求s,t之间的割点
思路:先spfa找一条最短路出来,如果不存在,就n个都是割点。
然后每次从s进行dfs,找到能经过最短路上的最远点,然后这个点就是割点,然后下次在以这个为起点dfs,不断迭代直到找到t为止
代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
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<int> 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;
}HDU 3313 Key Vertex(dfs + bfs)
标签:style blog http io color ar os sp for
原文地址:http://blog.csdn.net/accelerator_/article/details/40951357