HDU 3313 Key Vertex(dfs + bfs)

时间:2023-03-09 16:31:37
HDU 3313 Key Vertex(dfs + bfs)

HDU 3313 Key Vertex

题目链接

题意:一个有向无环图。求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;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。