CSU-暑假集训题 Graph Without Long Directed Paths

题目链接:http://codeforces.com/problemset/problem/1144/F

题目:

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 (2n2105, n1m2105

) — the number of vertices and edges, respectively.

The following m

lines contain edges: edge i is given as a pair of vertices ui, vi (1ui,vin, uivi). 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

思路

一开始我是对每条边的两个顶点染色(其实是做标记),比如黑红两色,如果一条边的两个顶点颜色相同,则输出NO,如果遍历所有边的两边的顶点都没有相同颜色,则输出YES。但是这有一个弊端,就是我一开始的想法是,如果都没有染色,就自己设置两个颜色,这是不对的,因为从某点开始染色后,其染色的结果是固定的,这样会影响最终的染色情况!所以染色是随机从一个顶点开始,然后通过dfs对相邻节点染不同颜色,这样才能保证正确性。

一开始错误的代码 :

#include<iostream>
using namespace std;
struct Enode{
    int u,v;
}node[200020];
int color[200020];
int ans[200020];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>node[i].u>>node[i].v;
    }
    for(int i=0;i<m;i++){
        int firstV=node[i].u,nextV=node[i].v;
        if(color[firstV]==color[nextV]&&color[firstV]!=0)
        {
            cout<<"NO"<<endl;
            return 0;
        }
        
        if(color[firstV]==0&&color[nextV]==0){
            color[firstV]=1;color[nextV]=2;
        }else if(color[firstV]==0&&color[nextV]!=0){
            if(color[nextV]==1)color[firstV]=2;
            else color[firstV]=1;
        }else if(color[firstV]!=0){
            if(color[nextV]==0){
                if(color[firstV]==1)color[nextV]=2;
                else color[nextV]=1;
            }
        }
        if(color[firstV]==1&&color[nextV]==2)ans[i]=0;
        else ans[i]=1;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++)cout<<ans[i];
    cout<<endl;
    return 0;
}

 

 

AC代码:

#include<iostream>
#include<vector>
using namespace std;
const int MAX=2e5+10;
vector<int>list[MAX];
int a[MAX],b[MAX];
int color[MAX];
int flag=1;
void dfs(int v,int fa,int col);
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        cin>>a[i]>>b[i];
        list[a[i]].push_back(b[i]);
        list[b[i]].push_back(a[i]);
    }
    for(int i=0;i<=n;i++)
    {
        color[i]=-1;
    }
    dfs(1,-1,0);
    if(!flag)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=0;i<m;i++)
    {
        if(color[a[i]]==1)cout<<1;
        else cout<<0;
    }
    cout<<endl;
    return 0;
}
void dfs(int v,int fa,int col)
{
    color[v]=col;
    int size=list[v].size();
    for(int i=0;i<size;i++)
    {
        int to=list[v][i];
        if(to==fa)continue;      //如果是前一个染色的节点 
        if(color[to]==-1)dfs(to,v,1-col);     //如果该节点未染色 
        else if(color[to]==color[v])flag=0;   //如果遍历到的节点的相邻节点与该节点颜色一致 
    }
}

 

posted @ 2019-07-25 11:17  小小笼包包  Views(114)  Comments(0)    收藏  举报