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;
        
} 
View Code

后记:

  • 遇到图,一定要看他是不是连通的
posted @ 2022-11-22 11:31  VxiaohuanV  阅读(49)  评论(0编辑  收藏  举报