zoukankan      html  css  js  c++  java
  • 寻找道路

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

    方法: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 }
  • 相关阅读:
    Constants and Variables
    随想
    C#基础篇之语言和框架介绍
    Python基础19 实例方法 类方法 静态方法 私有变量 私有方法 属性
    Python基础18 实例变量 类变量 构造方法
    Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()
    Python基础16 函数返回值 作用区域 生成器
    Python基础11 List插入,删除,替换和其他常用方法 insert() remove() pop() reverse() copy() clear() index() count()
    Python基础15 函数的定义 使用关键字参数调用 参数默认值 可变参数
    Python基础14 字典的创建修改访问和遍历 popitem() keys() values() items()
  • 原文地址:https://www.cnblogs.com/yufenglin/p/10703296.html
Copyright © 2011-2022 走看看