CodeForces 1144 F.Graph Without Long Directed Paths (二分图染色)

F.Graph Without Long Directed Paths

You are given a connected undirected graph consisting of n vertices and m edges. There are no self-loops or multiple edges in the given graph.

You have to direct its edges in such a way that the obtained directed graph does not contain any paths of length two or greater (where the length of path is denoted as the number of traversed edges).

Input

The first line contains two integer numbers n and m (2≤n≤2⋅105, n−1≤m≤2⋅105) — the number of vertices and edges, respectively.

The following m lines contain edges: edge i is given as a pair of vertices ui, vi (1≤ui,vi≤n, ui≠vi). There are no multiple edges in the given graph, i. e. for each pair (ui,vi) there are no other pairs (ui,vi) and (vi,ui) in the list of edges. It is also guaranteed that the given graph is connected (there is a path between any pair of vertex in the given graph).

Output

If it is impossible to direct edges of the given graph in such a way that the obtained directed graph does not contain paths of length at least two, print “NO” in the first line.

Otherwise print “YES” in the first line, and then print any suitable orientation of edges: a binary string (the string consisting only of ‘0’ and ‘1’) of length m. The i-th element of this string should be ‘0’ if the i-th edge of the graph should be directed from ui to vi, and ‘1’ otherwise. Edges are numbered in the order they are given in the input.

Example
Input

6 5
1 5
2 1
1 4
3 1
6 1

Output

YES
10100

题意:

给n个点m条边的无向图,现在要求把每条无向边改成有向边,
使得新图的任意路径长度都为1,

思路:

二分图染色

因为任意路径的长度大于等于2,因此每个顶点要么全部是出边,要么全部是入边,一个点只有一种状态
而相邻的点的状态和这个点相反。

发现和二分图染色基本一致:一个点一种颜色,相邻点相反,因此可以用二分图染色来做。

随便找一个点为起点,跑二分图染色,如果相邻的点已经被染色过且颜色相同说明无解。

染色的好处是边的方向很容易确定,因为两端点颜色不同,且相邻的边方向不同,
定义边的端点中u v的u染色为1则为起点或者为终点就行了,正好对应边的方向。

code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=2e5+5;
struct Node{
    int a,b;
}e[maxm];
vector<int>g[maxm];
int c[maxm];
int n,m;
void out(){
    cout<<"NO"<<endl;
    exit(0);
}
void dfs(int x,int fa,int cc){
    c[x]=cc;
    for(int v:g[x]){
        if(v==fa)continue;
        if(!c[v]){
            dfs(v,x,-cc);
        }else if(c[v]==c[x]){
            out();
        }
    }
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int a,b;
        cin>>a>>b;
        g[a].push_back(b);
        g[b].push_back(a);
        e[i]={a,b};
    }
    dfs(1,0,1);
    cout<<"YES"<<endl;
    for(int i=1;i<=m;i++){
        int a=e[i].a;
        cout<<(int)(c[a]==1);
    }
    cout<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值