zoukankan      html  css  js  c++  java
  • 【2014】

    D2T2 寻找道路

    一道相较于代码能力更考验思维的题。

    首先我们要意识到只跟终点有关的特殊性质,跑反向图是很常见的操作。

    因此这道题我们就是先从终点跑一遍反向图,把能到达终点的点标记出来,因为最后路径上的点绝对是从这些点中选,注意特判如果起点跑不到终点就直接输出-1然后return 0。

    接下来枚举这些能到达终点的点,先将它们都标记为路径上的点,再枚举它们的每一条边的终点,这些(当前枚举点对应的)终点有一个不能到达题目所给的终点,那么把已标记点去掉标记,表明它不能出现在路径上。

    最后bfs跑一个最短路,只能跑被标记的点即可。

    #include<bits/stdc++.h>
    #define ri register int
    #define ll long long
    #define For(i,l,r) for(ri i=l;i<=r;i++)
    #define Dfor(i,r,l) for(ri i=r;i>=l;i--)
    using namespace std;
    const int M=1e5+5;
    int dis[M],n,m,a,b,s,t;
    bool path[M],can[M];
    vector<int>side[M];
    vector<int>edis[M];
    queue<int>q;
    inline ll read(){
        ll f=1,sum=0;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
        return f*sum;
    }
    int main(){
        n=read(),m=read();
        For(i,1,m){
            a=read(),b=read();
            side[a].push_back(b);
            edis[b].push_back(a);
        }
        s=read(),t=read();
        can[t]=1;q.push(t);
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=edis[u].size()-1;i>=0;i--){
                int v=edis[u][i];
                if(!can[v]){
                    can[v]=1;
                    q.push(v);
                }
            }
        }
        if(!can[s]){printf("-1
    ");return 0;}
        For(i,1,n){
            if(can[i]){
                path[i]=1;
                for(int j=side[i].size()-1;j>=0;j--){
                    int v=side[i][j];
                    if(!can[v]){
                        path[i]=0;
                        break;
                    }
                }
            }
        }
        if(!path[s]){printf("-1
    ");return 0;}
        dis[s]=1;q.push(s);
        while(!q.empty()){
            int u=q.front();q.pop();
            if(u==t){printf("%d
    ",dis[t]-1);return 0;}
            for(int i=side[u].size()-1;i>=0;i--){
                int v=side[u][i];
                if(path[v]&&!dis[v]){
                    dis[v]=dis[u]+1;
                    q.push(v);
                }
            }
        }
        printf("-1
    ");
        return 0;
    }
    View Code
  • 相关阅读:
    监测你的SQL SERVER让瓶颈暴露
    SQL Server日志文件总结及日志满的处理
    SQL保持多台服务器数据的一致性
    SAS的函数
    业务单号自动增长的处理办法
    有一点迷茫了
    怎么强制弹出窗口永远在最前面(转)
    XML技术上传文件
    SQL复制表结构的通用存储过程(转)
    ACCESS中使用SQL语句应注意的地方、与sql server的区别及几点技巧(整理中)
  • 原文地址:https://www.cnblogs.com/jian-song/p/11867767.html
Copyright © 2011-2022 走看看