Cars (CF2E) (二分图+环判断+拓扑)

思路:
- 2个情况都是要方向不要才可以.
- 于是就二分图判断一下, 然后设一个方向即可.
- 位置的大小,就用有向图特性来表示
- 看看有没有环,有环就G, 用 tajain或者其他方法都可.
- 然后利用拓扑序处理即可

#include <bits/stdc++.h> using namespace std; #define ri register int #define M 2000005 int n,m; vector <int> p[M]; struct dian{ int op; int a,b; }q[M]; int flag=1; int col[M]; void dfs(int a) { for(ri i=0;i<p[a].size();i++) { int b=p[a][i]; if(col[b]) { if(col[b]==col[a]) { flag=0; } } else { col[b]=col[a]^1; dfs(b); } } } int low[M],dfn[M],vis[M]; int cnt=0; int qu[M],r=0; void tj(int a){ low[a]=dfn[a]=++cnt; vis[a]=1; qu[++r]=a; for(ri i=0;i<p[a].size();i++) { int b=p[a][i]; if(dfn[b]==0) { tj(b); low[a]=min(low[a],low[b]); } else if(vis[b]) low[a]=min(low[a],dfn[b]); } if(dfn[a]==low[a]) { int tmp=0; while(1) { int b=qu[r--]; tmp++; vis[b]=0; if(b==a||r==0) break; } if(tmp>1) { flag=0; } } } int in[M],out[M]; queue<int>qq; int ans[M]; int num=-1e9; void bfs(){ while(!qq.empty()) { int a=qq.front();qq.pop(); ans[a]=++num; for(ri i=0;i<p[a].size();i++) { int b=p[a][i]; in[b]--; if(in[b]==0) qq.push(b); } } } int main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin>>n>>m; for(ri i=1;i<=m;i++) { int op,a,b; cin>>op>>a>>b; q[i].op=op;q[i].a=a;q[i].b=b; p[a].push_back(b); p[b].push_back(a); } for(ri i=1;i<=n;i++) { if(col[i]==0) col[i]=2,dfs(i); } if(flag==0) { cout<<"NO\n"; return 0; } for(ri i=1;i<=n;i++) p[i].clear(); for(ri i=1;i<=m;i++) { int a=q[i].a,b=q[i].b; if(q[i].op==1) { if(col[a]==2) p[a].push_back(b),in[b]++; else p[b].push_back(a),in[a]++; } else { if(col[a]==3) p[a].push_back(b),in[b]++; else p[b].push_back(a),in[a]++; } } for(ri i=1;i<=n;i++) { if(dfn[i]==0) tj(i); } if(flag==0) { cout<<"NO\n"; return 0; } for(ri i=1;i<=n;i++) { if(in[i]==0) { qq.push(i); } } bfs(); cout<<"YES\n"; for(ri i=1;i<=n;i++) { if(col[i]==2) cout<<"L "; else cout<<"R "; cout<<ans[i]<<"\n"; } return 0; }
后记:
- 遇到图,一定要看他是不是连通的