码迷,mamicode.com
首页 > 其他好文 > 详细

寻找道路

时间:2019-04-13 23:16:28      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:string   algorithm   max   include   front   class   running   ret   names   

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

方法: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\n");
 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\n");
111     else printf("%d\n",dis[t]);
112     return 0;
113 }

 

寻找道路

标签:string   algorithm   max   include   front   class   running   ret   names   

原文地址:https://www.cnblogs.com/yufenglin/p/10703296.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!