CodeForces - 915D Almost Acyclic Graph 拓扑排序

题目:

D. Almost Acyclic Graph
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given a directed graph consisting of n vertices and m edges (each edge is directed, so it can be traversed in only one direction). You are allowed to remove at most one edge from it.

Can you make this graph acyclic by removing at most one edge from it? A directed graph is called acyclic iff it doesn't contain any cycle (a non-empty path that starts and ends in the same vertex).

Input

The first line contains two integers n and m (2 ≤ n ≤ 5001 ≤ m ≤ min(n(n - 1), 100000)) — the number of vertices and the number of edges, respectively.

Then m lines follow. Each line contains two integers u and v denoting a directed edge going from vertex u to vertex v (1 ≤ u, v ≤ nu ≠ v). Each ordered pair (u, v) is listed at most once (there is at most one directed edge from u to v).

Output

If it is possible to make this graph acyclic by removing at most one edge, print YES. Otherwise, print NO.


题意:给出一个有向图,如果从中任意删除至多一条边。问是否可以最终使图变为无环图。


思路:我们知道拓扑排序来判断是否有环,就是不断删除入度为0的点(删除时只关注节点入度!),最终比较删除次数和点的关系。

而本题由于至多删除一条边,而删除一条边引起的变化就是某一点的入度减一。于是我们可以枚举每个点入度减一的情况,然后跑拓扑排序判断是否还有环的存在。

代码:

#include<bits/stdc++.h>
#define sd(x) scanf("%d",&x)
#define ss(x) scanf("%s",x)
#define sc(x) scanf("%c",&x)
#define sf(x) scanf("%f",&x)
#define slf(x) scanf("%lf",&x)
#define slld(x) scanf("%lld",&x)
#define me(x,b) memset(x,b,sizeof(x))
#define pd(d) printf("%d\n",d);
#define plld(d) printf("%lld\n",d);
#define eps 1.0E-8
// #define Reast1nPeace

typedef long long ll;

using namespace std;

const int maxn = 510;

int n,m;

vector<int> G[maxn];
int in1[maxn];
int in2[maxn];

bool topsort(){
	queue<int> q;
	for(int i = 1 ; i<=n ; i++){
		if(!in2[i])	q.push(i);
	}
	int sum = 0;
	while(!q.empty()){
		int now = q.front(); q.pop();
		sum++;
		for(int i = 0 ; i<G[now].size() ; i++){
			int to = G[now][i];
			in2[to]--;
			if(!in2[to])	q.push(to);
		}
	}
	return sum==n;
}

int main(){
#ifdef Reast1nPeace
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
#endif
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i = 1 ; i<=m ; i++){
		int u,v; cin>>u>>v;
		G[u].push_back(v);
		in1[v]++;
	} 
	
	topsort();
	memcpy(in2,in1,sizeof(in1));
	if(topsort()){
		cout<<"YES"<<endl;
	}
	else{
		bool flag = 0;
		for(int i = 1 ; i<=n ; i++){
			if(in1[i]){
				memcpy(in2,in1,sizeof(in1));
				in2[i]--;
				if(topsort()){
					flag = 1;
					break;
				}
			}
		}
		if(flag){
			cout<<"YES"<<endl;
		}
		else{
			cout<<"NO"<<endl;
		}
	}
	return 0;
}


猜你喜欢

转载自blog.csdn.net/Reast1nPeace/article/details/80171708