Graph Without Long Directed Paths CodeForces - 1144F
题目
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
Note
The picture corresponding to the first example:
And one of possible answers:
题目分析
给定一个无向图,让其把边变成一个有向边,要求最后的图中任何一个路径的长度只能为1。
通过分析题目我们可以发现,要满足图中的任意一个路径的长度不大于等于2的话,那么对于任意一个节点i,如果它在一个边中做起点,那么就不能在另一个边中做终点。
这里使用dfs解题,具体解题思路详见代码注释。
代码
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int Max = 200010; //一定要比 200000大,否则可能通过不了
int m,n;
int u[Max],v[Max];
int flag[Max]; //每个点的状态
vector<int> vc[Max]; //vector数组,是为了动态的添加每个点所相连的点
bool dfs(int i,int f){
if(flag[i] == -1) flag[i] = f;
if(flag[i] != f) return false; //成环,输出no
for(int j = 0;j < vc[i].size();j++){ //深度搜索与i点相连的点
if(flag[vc[i][j]] == -1){
if(!dfs(vc[i][j],f^1)) return false; //使f与1异或,保证每个点只作为一次起点
}else if(flag[vc[i][j]] == f) //成环,输出no
return false;
}
return true;
}
int main(){
cin>>m>>n;
memset(flag, -1, sizeof(flag)); //初始化-1,代表未被访问
for(int i = 0;i < n;i++){
cin>>u[i]>>v[i];
vc[u[i]].push_back(v[i]);
vc[v[i]].push_back(u[i]);
}
if(dfs(1,0)){
cout<<"Yes"<<endl;
for(int i = 0;i < n;i++){
cout<<flag[v[i]];
}
cout<<endl;
}else{
cout<<"NO"<<endl;
}
return 0;
}