luogu 2296 寻找道路

luogu 2296 寻找道路

题目链接:https://www.luogu.org/problemnew/show/P2296
从终点bfs或者dfs,找出所有终点能到达的点.
然后再从1到n看一下出边是否都与终点相连.
然后对于可行的边,做最短路即可.
因为这里的边权是1,所以bfs即可.
CODE:

#include <iostream>
#include <cstdio>
#include <queue>
const int maxN = 20000 + 7;
const int maxM = 400000 + 7;
using namespace std;

struct Node {
    int v,nex;
}Map[maxM];
int head[maxN],num;
bool vis[maxN];

void add_Node(int u,int v) {
    Map[++ num] = (Node) {v,head[u]};
    head[u] = num;
    return ;
}

struct Node_2 {
    int v,nex;
}Map_2[maxM];
int num_2,head_2[maxN],dep[maxN];
bool vis2[maxN];

void add_Node2(int u,int v) {
    Map_2[++ num_2] = (Node_2) {v,head_2[u]};
    head_2[u] = num_2;
    return ;
}

queue<int> q;

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

int main() {
    int n,m,s,t,u,v;
    n = read();m = read();
    while(m --) {
        u = read();v = read();
        add_Node2(u,v);
        add_Node(v,u);
    }
    s = read();t = read();
    vis[t] = true;
    q.push(t);
    while(!q.empty()) {
        u = q.front();q.pop();
        for(int i = head[u];i;i = Map[i].nex) {
            v = Map[i].v;
            if(!vis[v]) {
                vis[v] = true;
                q.push(v);
            }
        }
    }
    for(int i = 1;i <= n;++ i) {
        if(!vis[i]) vis2[i] = true;
        for(int j = head_2[i];j;j = Map_2[j].nex) {
            int v = Map_2[j].v;
            if(!vis[v]) vis2[i] = true;
        }
    }
    dep[t] = 1;
    q.push(t);
    while(!q.empty()) {
        int p = q.front();q.pop();
        for(int i = head[p];i;i = Map[i].nex) {
            int v = Map[i].v;
            if(!dep[v] && !vis2[v]) {
                q.push(v);
                dep[v] = dep[p] + 1;
            }
        }
    }
    printf("%d",dep[s] == 0 ? -1 : dep[s] - 1);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tpgzy/p/9715071.html