HDU - 3313 Key Vertex(在最短路上的DFS)

来源:互联网 发布:联想网络控制程序密码 编辑:程序博客网 时间:2024/06/11 16:27

题目大意:给出N个点,M条有向边,每条有向边的长度为1,现在给出起点和终点,问这张图上有多少个点满足去掉该点后,使得起点到终点不连通(起点和终点也算)

解题思路:先求出最短路,因为长度都是1,所以最短路中的点肯定是最少的
去掉点,且使起点和终点不连通的点肯定是最短路上的点
把最短路上的点标记一下,然后从起点出发进行DFS,如果遇到标记过的点,就将起点重新赋值为走到的最远的标记的点,直到走到终点,dfs几次,就表示有多少个点是关键点,因为我们遇到了标记过的点就直接跳过,相当于不走该点

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int MAXNODE = 100010;const int MAXEDGE = 300010;const int INF = 0x3f3f3f3f;int S, T, tot, n, m;int head[MAXNODE], tmp[MAXNODE], pre[MAXNODE], d[MAXNODE];bool vis[MAXNODE], mark[MAXNODE];struct Edge{    int v, next;    Edge() {}    Edge(int v, int next): v(v), next(next) {}}E[MAXEDGE];void AddEdge(int u, int v) {    E[tot] = Edge(v, head[u]);    head[u] = tot++;}void init() {    memset(head, -1, sizeof(head));    tot = 0;    int u, v;    for (int i = 0; i < m; i++) {        scanf("%d%d", &u, &v);        AddEdge(u, v);    }    scanf("%d%d", &S, &T);}bool BellmanFord() {    for (int i = 0; i < n; i++) {        d[i] = INF; vis[i] = false;    }    queue<int> Q;    d[S] = 0;    Q.push(S);    while (!Q.empty()) {        int u = Q.front(); Q.pop();        for (int i = head[u]; ~i; i = E[i].next) {            int v = E[i].v;            if (d[v] > d[u] + 1) {                d[v] = d[u] + 1;                pre[v] = u;                if (!vis[v]) {                    vis[v] = true;                    Q.push(v);                }            }        }        vis[u] = false;    }    if (d[T] == INF) return false;    int t = T;    memset(mark, 0, sizeof(mark));    while (t != S) {        mark[t] = true;        t = pre[t];    }    return true;}void dfs(int u) {    for (int i = head[u]; ~i; i = E[i].next) {        int v = E[i].v;        if (vis[v]) continue;        vis[v] = true;        if (mark[v]) {            if (d[v] > d[S]) S = v;            continue;        }        dfs(v);    }}int main() {    while (scanf("%d%d", &n, &m) != EOF) {        init();        if ( !BellmanFord()) printf("%d\n", n);        else {            memset(vis, 0, sizeof(vis));            int ans = 1;            while(S != T) {                dfs(S);                ans++;            }            printf("%d\n", ans);        }    }    return 0;}
0 0