Graph Without Long Directed Paths CodeForces - 1144F 题解

这是一篇关于CodeForces 1144F题目的解题报告。题目要求将一个无向图定向,使得形成的有向图中不存在长度大于等于2的路径。解决方案是通过深度优先搜索(DFS)确保每个节点作为起点的边不会指向其他节点作为起点的边。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值