• 寻找道路


    题目大意:给定一个有向图,找到一条满足路径上的所有点的出边所指向的点都直接或间接与终点连通条件的最短路径。

    方法:dfs+SPFA

    首先,我们需要判断图上哪些点可以走,哪些点不可以走。

    我们对于每一个边建一个边权为-1的反向边,从终点开始dfs,这样一来我们就可以知道那些点与终点相连了。

    接着,我们枚举每一个点,枚举他的每一条出边,如果都能到终点,就代表这个点可以走

    然后,我们跑一遍SPFA求最短路即可(注意判断只能走标记能走的点)

    时间复杂度:O(vn)最慢的也就是SPFA了,但是本题数据小,还是能过去的。

    最后,附上本题代码:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<queue>
      7 using namespace std;
      8 //Debug Yufenglin
      9 #define dej printf("Running
    ");
     10 #define dep1(x) cout<<#x<<"="<<x<<endl;
     11 #define dep2(x,y) cout<<#x<<"="<<x<<' '<<#y<<"="<<y<<endl;
     12 #define dep3(x,y,z) cout<<#x<<"="<<x<<' '<<#y<<"="<<y<<' '<<#z<<"="<<z<<endl;
     13 
     14 //Standfor Yufenglin
     15 #define LL long long
     16 #define LB long double
     17 #define reg register
     18 #define il inline
     19 #define maxn 10000
     20 #define maxm 200000
     21 #define inf 1000000000
     22 
     23 int n,m,cnt,s,t;
     24 struct EDGE
     25 {
     26     int to,nxt,v;
     27 };
     28 EDGE edge[maxm*2+5];
     29 bool canvis[maxn+5],vis[maxn+5],visited[maxn+5];
     30 int dis[maxn+5],head[maxn+5];
     31 queue<int>q;
     32 
     33 void add(int x,int y,int z)
     34 {
     35     edge[++cnt].to=y;
     36     edge[cnt].v=z;
     37     edge[cnt].nxt=head[x];
     38     head[x]=cnt;
     39 }
     40 void dfs(int x)
     41 {
     42     //canvis[x]=1;
     43     for(int i=head[x]; i; i=edge[i].nxt)
     44     {
     45         if(edge[i].v==-1&&canvis[edge[i].to]==0)
     46         {
     47             canvis[edge[i].to] = 1;
     48             dfs(edge[i].to);
     49         }
     50     }
     51 }
     52 void SPFA()
     53 {
     54     for(int i=1; i<=n; i++)
     55     {
     56         dis[i]=inf;
     57     }
     58     int u=s;
     59     dis[u]=0;
     60     vis[u]=1;
     61     q.push(u);
     62     while(!q.empty())
     63     {
     64         u=q.front();
     65         vis[u]=0;
     66         q.pop();
     67         for(int i=head[u]; i; i=edge[i].nxt)
     68         {
     69             if(visited[edge[i].to]==0) continue;
     70             if(dis[edge[i].to]>dis[u]+1)
     71             {
     72                 dis[edge[i].to]=dis[u]+1;
     73                 if(vis[edge[i].to]==0)
     74                 {
     75                     vis[edge[i].to]=1;
     76                     q.push(edge[i].to);
     77                 }
     78             }
     79         }
     80     }
     81 }
     82 int main()
     83 {
     84     scanf("%d%d",&n,&m);
     85     for(int i=1; i<=m; i++)
     86     {
     87         int x,y;
     88         scanf("%d%d",&x,&y);
     89         if(x==y) continue;
     90         add(x,y,1);
     91         add(y,x,-1);
     92     }
     93     scanf("%d%d",&s,&t);
     94     canvis[t] = 1;
     95     dfs(t);
     96     for(int i=1; i<=n; i++)
     97     {
     98         bool flag=1;
     99         for(int j=head[i];j;j=edge[j].nxt)
    100         {
    101             if(canvis[edge[j].to]==0)
    102             {
    103                 flag=0;
    104                 break;
    105             }
    106         }
    107         if(flag==1) visited[i]=1;
    108     }
    109     SPFA();
    110     if(dis[t]==inf) printf("-1
    ");
    111     else printf("%d
    ",dis[t]);
    112     return 0;
    113 }
  • 相关阅读:
    排序
    git常用操作_分支合并_新建工程等
    ibatis 中调用存储过程
    IDEA试用期结束激活问题
    kafka本地工程的调用说明
    python yield 和 yield from用法总结
    ubuntu14.06 Lts开启ssh服务
    QT-1-环境搭建QT5.4.1&MinGW4.9.1
    虚拟机Ping不通主机解决
    CRC类(处理ITU表)
  • 原文地址:https://www.cnblogs.com/yufenglin/p/10703296.html
Copyright © 2020-2023  润新知