寻找道路
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
以上是关于寻找道路的主要内容,如果未能解决你的问题,请参考以下文章