E. Cars 題解(二分圖染色+拓撲排序)
阿新 • • 發佈:2022-02-21
題目連結
題目思路
官方題解說的很好連結
本質上就是不管能不能相撞,只要有關聯,那麼他們的方向肯定相反
那麼首先根據方向建圖,然後判斷是否滿足二分圖
那麼第二步重新建圖,跑拓撲排序即可,感覺有點意思
程式碼
不擺爛了,寫題#include<bits/stdc++.h> #define fi first #define se second #define debug cout<<"I AM HERE"<<endl; using namespace std; typedef long long ll; const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7; const double eps=1e-6; int n,m; vector<int> g[maxn]; int opt[maxn],u[maxn],v[maxn]; int vis[maxn]; int deg[maxn]; int ans[maxn]; void dfs(int x,int now){ for(auto nxt:g[x]){ if(vis[nxt]!=-1) continue; vis[nxt]=(now^1); dfs(nxt,now^1); } } bool check(){ memset(vis,-1,sizeof vis); for(int i=1;i<=n;i++){ if(vis[i]==-1){ vis[i]=0; dfs(i,0); } } for(int i=1;i<=m;i++){ if(vis[u[i]]==vis[v[i]]){ return 0; } } return 1; } bool topo(){ int pos=1; queue<int> que; for(int i=1;i<=n;i++){ if(deg[i]==0){ que.push(i); } } while(!que.empty()){ int x=que.front(); que.pop(); ans[x]=pos++; for(auto nxt:g[x]){ deg[nxt]--; if(deg[nxt]==0){ que.push(nxt); } } } for(int i=1;i<=n;i++){ if(deg[i]!=0){ return 0; } } return 1; } signed main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&opt[i],&u[i],&v[i]); g[u[i]].push_back(v[i]); g[v[i]].push_back(u[i]); } if(!check()){ printf("NO\n"); return 0; } for(int i=1;i<=n;i++){ g[i].clear(); } for(int i=1;i<=m;i++){ if(vis[v[i]]==0){ swap(u[i],v[i]); } if(opt[i]==1){ g[u[i]].push_back(v[i]); deg[v[i]]++; }else{ g[v[i]].push_back(u[i]); deg[u[i]]++; } } if(!topo()){ printf("NO\n"); return 0; } printf("YES\n"); for(int i=1;i<=n;i++){ printf("%c %d\n",vis[i]==1?'R':'L',ans[i]); } return 0; }