题意:
给定一个无向图,判断它可不可以变成一个有向图,使得这个图不存在长度为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;
}