codeforces #550-F(二分图判定)

传送门

题意:

给定一个无向图,判断它可不可以变成一个有向图,使得这个图不存在长度为2的路径

输入

第一行输入 n,m代表有n个点,m条边

接下来m行代表

输入ui,vi 代表ui,vi 是一条边

输出

如果可以构成的话,那么首先输出一个YES,然后输出一个只有01组成的序列,

0的话代表是ui指向vi

1的话是代表vi指向ui

否则输出NO

样例

6 5
1 5
2 1
1 4
3 1
6 1
YES
10100

思路

在有向图中,如果存在一条路径为2的话,那么在这条路径上肯定有一个点是入度和出度都大于0 的,就是有进有出的,我在这里把它叫做中转点,意思就是其他点可以通过它到另一个点。所以我只要保证我的有向图中不存在中转点就行了,也就是让每个点的入度要么为0同时出度不为0,或者是出度为0,入度不为0。

就是看能不能把所有点分成两个集合,这里的话就可以用判断二分图的染色法来判断了

code

#include <iostream>
#include <vector>
using namespace std;
const int maxn=2e5+10;
int color[maxn];
int vis[maxn];
int m,n;
vector<int>ans[maxn];
struct li
{
    int u,v;
};
li graph[maxn];

int flg=1;
void dfs(int s,int c){
    if(vis[s])return ;
    color[s]=c;
    vis[s]=1;
    int len=ans[s].size();
    
    for(int i:ans[s]){
            if(!vis[i]){
                dfs(i,c^1);
            }
            else {
                if(color[i]==color[s]){
                    flg=0;
                    return ;
                }
            }
    }
    return ;
    
}
int main(){
    cin>>n>>m;
    int u,v;
    for(int i=0;i<m;i++){
        cin>>u>>v;
        graph[i].u=u;
        graph[i].v=v;
        ans[u].push_back(v);
        ans[v].push_back(u);
    }
    dfs(1,1);
    
    if(!flg){cout<<"NO"<<endl;
    return 0;}
    cout<<"YES\n";
    for(int i=0;i<m;i++){
        u=graph[i].u;
        v=graph[i].v;
        if(color[u]==0){
            cout<<'0';
        }
        else cout<<'1';
    }
    return 0;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值