标签: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