【bf】洛谷 P2296 寻找道路 暴力

版权声明:随便转载。 https://blog.csdn.net/zhang14369/article/details/80800461

一、题目:

洛谷原题

二、思路:

这是暴力做法,正解请看下一篇
floyd(传递闭包)+ SPFA。
用传递闭包标记哪些点和终点联通,然后跑SPFA,在判断点是否入队是增加一条判断条件——是否与终点连通。

Tips:在这道题中,SPFA的实质是BFS,我习惯叫它为SPFA。

注意起点的特判。
得分:60分。

三、代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>

using namespace std;
inline int read(void) {
    int x = 0, f = 1; char ch = getchar();
    while (ch<'0' || ch>'9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch >= '0'&&ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return f * x;
}

const int maxn = 10005, maxm = 200005;

int n, m, head[maxn], tot, start, en, dis[maxn], flag[maxn][maxn];
bool vis[maxn];


struct Edge {
    int y, next;
}e[maxm];

inline void connect(int x, int y) {
    e[++tot].y = y; e[tot].next = head[x]; head[x] = tot;
}

inline bool check(int node) {
    for (register int i = head[node]; i; i = e[i].next) {
        if (!flag[e[i].y][en])return false;
    }
    return true;
}

inline void init(void) {
    n = read(); m = read();
    for (register int i = 1; i <= m; i++) {
        int x = read(), y = read();
        if (x == y)continue;
        if (flag[x][y])continue;
        flag[x][y] = true;
        connect(x, y);
    }
    start = read(); en = read();
    for (register int i = 1; i <= n; i++)flag[i][i] = true;
    for (register int k = 1; k <= n; k++)
        for (register int i = 1; i <= n; i++)
            for (register int j = 1; j <= n; j++) 
                flag[i][j] |= (flag[i][k] && flag[k][j]);
}

inline void solve(void) {
    queue<int>q; q.push(start);
    vis[start] = true;
    memset(dis, 0x3f, sizeof(dis)); dis[start] = 0;
    while (q.size()) {
        int u = q.front(); q.pop(); vis[u] = false;
        for (register int i = head[u]; i; i = e[i].next) {
            int y = e[i].y;
            if (dis[y] > dis[u] + 1 && check(y)) {
                dis[y] = dis[u] + 1;
                if (!vis[y]) {
                    q.push(y); vis[y] = true;
                }
            }
        }
    }
    if (dis[en] == 0x3f3f3f3f) { puts("-1"); }
    else printf("%d\n", dis[en]);
}

int main()
{
    init();
    if (!flag[start][en]) { puts("-1"); return 0; }
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zhang14369/article/details/80800461