题目链接
题目思路
官方题解说的很好链接
本质上就是不管能不能相撞,只要有关联,那么他们的方向肯定相反
那么首先根据方向建图,然后判断是否满足二分图
那么第二步重新建图,跑拓扑排序即可,感觉有点意思
代码
#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;
}