寻找道路

Posted lcan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寻找道路相关的知识,希望对你有一定的参考价值。

预处理出不能用的点:

一开始用的是搜索,处理环的时候是错的......可能绕了一圈回来可以到终点

所以......其实只要反着加边,在拓扑是处理就好了......

错误代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 using namespace std;
 6 #define debug(x)cout<<#x<<" = "<<x<<endl;
 7 typedef unsigned long long ll;
 8 const ll maxn=1e4+7;
 9 const ll maxm=200000+7;
10 const ll inf=2147483647;
11 ll n,m,s,t;
12 ll head[maxn],num,rec[maxn],d[maxn];
13 ll map[20]={2243,9282,2299,3304,612,2613,7298,8673,8480,4144,7815,3280,3060,228,2825,9820,115,6251,};
14 queue<ll>q;
15 bool inq[maxn];
16 struct Edge{
17     ll next,to,dis;
18 }edge[maxm];
19 void add(ll from,ll to,ll dis){
20     edge[++num].next=head[from];
21     edge[num].to=to;
22     edge[num].dis=dis;
23     head[from]=num;
24 }
25 void dfs(ll x){
26     if(rec[x]==1||rec[x]==2) return;
27     bool flag=true;
28     if(head[x]==0){
29         if(x==t) rec[x]=1;
30         else rec[x]=2;
31         return;
32     }
33     rec[x]=-1;
34     for(ll i=head[x];i;i=edge[i].next){
35         ll v=edge[i].to;
36         if(rec[v]==-1) {flag=false;break;}
37         if(rec[v]==0) dfs(v);
38         if(rec[v]==2) {flag=false;break;}
39     } 
40     if(flag==false) rec[x]=2;
41     else rec[x]=1;
42     return;
43 } 
44 void spfa(ll x){
45     memset(d,inf,sizeof(d));
46     memset(inq,false,sizeof(inq));
47     d[x]=0;q.push(x);inq[x]=false;
48     while(!q.empty()){
49         ll u=q.front();q.pop();inq[u]=false;
50         for(ll i=head[u];i;i=edge[i].next){
51             ll v=edge[i].to;
52             if(rec[v]==2) continue;
53             if(d[v]>d[u]+edge[i].dis){
54                 d[v]=d[u]+edge[i].dis;
55                 if(inq[v]==false){
56                     inq[v]=true;q.push(v);
57                 }
58             }
59         } 
60     }
61 }
62 int main(){
63     cin>>n>>m;
64     for(ll i=1;i<=m;i++){
65         ll x,y;cin>>x>>y;
66         add(x,y,1);
67     }
68     cin>>s>>t;
69     for(ll i=1;i<=n;i++){
70         if(rec[i]==0) dfs(i);
71     }
72     for(int i=1;i<=n;i++) cout<<rec[i]<<" ";
73     cout<<endl;
74     spfa(s);
75     if(d[t]==inf) cout<<"-1"<<endl;
76     else cout<<(int)d[t]<<endl;
77     return 0;
78 } 

正确代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 using namespace std;
 6 #define debug(x)cout<<#x<<" = "<<x<<endl;
 7 typedef unsigned long long ll;
 8 const ll maxn=1e4+7;
 9 const ll maxm=200000+7;
10 const ll inf=2147483647;
11 ll n,m,s,t;
12 ll head[maxn],num,rec[maxn],d[maxn];
13 ll map[20]={2243,9282,2299,3304,612,2613,7298,8673,8480,4144,7815,3280,3060,228,2825,9820,115,6251,};
14 queue<ll>q;
15 bool inq[maxn];
16 struct Edge{
17     ll next,to,dis;
18 }edge[maxm];
19 struct EDGE{
20     int next;int to;
21 }edge2[maxm];
22 int num2,head2[maxn],ind[maxn];
23 void add2(int from,int to){
24     edge2[++num2].next=head2[from];
25     edge2[num2].to=to;
26     head2[from]=num2;
27 }
28 void add(ll from,ll to,ll dis){
29     edge[++num].next=head[from];
30     edge[num].to=to;
31     edge[num].dis=dis;
32     head[from]=num;
33 }
34 void process(){
35     
36 }
37 void spfa(ll x){
38     memset(d,inf,sizeof(d));
39     memset(inq,false,sizeof(inq));
40     d[x]=0;q.push(x);inq[x]=false;
41     while(!q.empty()){
42         ll u=q.front();q.pop();inq[u]=false;
43         for(ll i=head[u];i;i=edge[i].next){
44             ll v=edge[i].to;
45             if(rec[v]==2) continue;
46             if(d[v]>d[u]+edge[i].dis){
47                 d[v]=d[u]+edge[i].dis;
48                 if(inq[v]==false){
49                     inq[v]=true;q.push(v);
50                 }
51             }
52         } 
53     }
54 }
55 int main(){
56     cin>>n>>m;
57     for(int i=1;i<=n;i++) rec[i]=1;
58     for(ll i=1;i<=m;i++){
59         ll x,y;cin>>x>>y;
60         add(x,y,1);add2(y,x);ind[x]++;
61     }
62     cin>>s>>t;
63     for(int i=1;i<=n;i++){
64         if(ind[i]==0&&i!=t){
65             q.push(i);rec[i]=2;
66         }
67     }
68     while(!q.empty()){
69         int u=q.front();q.pop();
70         for(int i=head2[u];i;i=edge2[i].next){
71             int v=edge2[i].to;
72             rec[v]=2;ind[v]--;
73             if(ind[v]==0) q.push(v);
74         }
75     }
76     spfa(s);
77     if(d[t]==inf) cout<<"-1"<<endl;
78     else cout<<(int)d[t]<<endl;
79     return 0;
80 } 

 所以要提高思考能力,考试时并没有数据来让你找错

Think twice,code once

以上是关于寻找道路的主要内容,如果未能解决你的问题,请参考以下文章

寻找道路(NOIP2014)神奇之题。。

[NOIP2014]寻找道路 题解

洛谷P2296 寻找道路==codevs3731 寻找道路

[UOJ] #19 寻找道路

LuoGuP2296寻找道路

P2296 寻找道路