• 【luogu】p2296 寻找道路


    首先我们可以作为路径中的点的节点一定会满足它的子节点全部和终点连通

    那么就要找出所有能和终点连通的点

    考虑反向建边,从终点开始遍历,将能与它连通的点打上标记

    再暴力枚举每一个点,如果它出边所连接的点中有不和终点连接的点就删除这个点

    再对剩余的点到终点求一个最短路就可以

    由于所有边边权都是1直接用bfs就可以求出最短路

    (但我是憨憨所以没用)

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<string>
    #include<cstring>
    using namespace std;
    int read(){
        int a = 0,f = 0;char p = getchar();
        while(!isdigit(p)){f|=p=='-';p = getchar();}
        while(isdigit(p)){a=(a<<3) + (a<<1) +(p^48);p = getchar();}
        return f?-a:a;
    }
    vector<int> mmp[10001];
    vector<int> f[10001];
    int n,m,s,t;
    queue<int> q;
    bool flag[20000];//?ж???????
    bool del[20000];//????????
    bool vis[20000];
    priority_queue<pair<int,int> > qwq;
    int dis[20000];
    void bfs(int x){
        q.push(x);
        flag[x] = 1;
        while(!q.empty()){
            int u = q.front();
            //cout<<u<<endl;
            for(int i = 0;i < f[u].size();i++){
                if(!flag[f[u][i]]){
                    flag[f[u][i]] = 1;
                    q.push(f[u][i]);
                }
            }
            q.pop();
        }
    }
    void delet(){
        for(int i = 1;i <= n;i ++){
            for(int j = 0;j < mmp[i].size();j++){
                int v = mmp[i][j];
                if(flag[v] == 0){
                    //cout<<v<<" "<<i<<endl;
                    del[i] = 1;}
            }
        }
    }
    void _short(){
        //cout<<"FUCKKKK";
        int x,y;
        memset(dis,1061109567,sizeof(dis));
        dis[s] = 0;
        qwq.push(make_pair(0,s));//答案 编号
        while(!qwq.empty()){
            x = qwq.top().second;
            qwq.pop();
            if(vis[x])continue;
            vis[x] = 1;
            for(int i = 0;i < mmp[x].size();i++){
                y = mmp[x][i];
                if(del[y])continue;
                if(dis[y] > dis[x] + 1){
                    dis[y] = dis[x] + 1;
                    qwq.push(make_pair(-dis[x]-1,y));
                }
            }
        }
        //for(int i = 1; i<= n; i++)cout<<dis[i]<<endl;
        if(dis[t] >= 1061109567)cout<<-1<<endl;
        else cout<<dis[t]<<endl;
    }
    int main(){
        //cout<<0x3f<<endl;
        n = read();m = read();
        int x,y;
        for(int i = 1;i <= m;i++){
            x = read();y = read();
            if(x == y)continue;
            mmp[x].push_back(y);//??x??y???????
            f[y].push_back(x);//??????
        }
        s = read();t = read();
        bfs(t);
        if(flag[s] == 0){cout<<"-1";return 0;}
        delet();
        if(del[s] == 1){cout<<"-1";return 0;}
        _short();
    }
    
    
  • 相关阅读:
    容器技术问题
    URL和URL
    容器和注入技术
    云计算应用开发与实践读书 笔记(三)
    云计算应用开发与实践读书 笔记 (二 )
    云计算应用开发与实践读书 笔记
    C++学习之DLL注入
    c语言学习,模拟栈操作
    领悟百分比定位
    强大的第三方工具autoPrefixer
  • 原文地址:https://www.cnblogs.com/huixinxinw/p/12236699.html
Copyright © 2020-2023  润新知