• 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;
    }
    
    
    
    
    
    
  • 相关阅读:
    (转)Java 调用 C++ (Java 调用 dll)
    用Gvim建立IDE编程环境 (Windows篇)
    (转)python调取C/C++的dll生成方法
    C/C++协程的实现方式总结
    时钟周期,机器周期,指令周期,总线周期
    (转)MongoDB和Redis区别
    linux cpu占用100%排查
    (转)linux 打开文件数 too many open files 解决方法
    Python下载网页图片
    python抓网页数据【ref:http://www.1point3acres.com/bbs/thread-83337-1-1.html】
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/15919519.html
Copyright © 2020-2023  润新知