1. 程式人生 > 其它 >E. Cars 題解(二分圖染色+拓撲排序)

E. Cars 題解(二分圖染色+拓撲排序)

題目連結

題目思路

官方題解說的很好連結

本質上就是不管能不能相撞,只要有關聯,那麼他們的方向肯定相反

那麼首先根據方向建圖,然後判斷是否滿足二分圖

那麼第二步重新建圖,跑拓撲排序即可,感覺有點意思

程式碼

#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;
}





不擺爛了,寫題