CF915D Almost Acyclic Graph

题意

给定一张 nn 个点 mm 条边的图,问是否可以删除一条边使得整个图没有环。

解法

先考虑暴力,删除每一条边用拓扑排序判断环,复杂度 O(m×(m+n))=O(m2+mn)O(m \times (m + n)) = O(m^2 + m \cdot n),明显 O(m2)O(m^2) 已经承受不下,因为这是一个稠密图。

考虑删边的本质,其实就是将那条有向边的终点的入度 1-1,考虑对于每一个入度 1\ge 1 的点的入度 1-1,复杂度 O(n×(m+n))O(n \times (m+n)),可以通过。

另外注意,每次拓扑后入度数组会改变,要两个数组储存,我一开始就是因为这个错了好多次。

用时:810ms810ms

代码:

#ifdef ONLINE_JUDGE
#pragma GCC optimize(2)
#endif
#include <bits/stdc++.h>
using namespace std;

const int N = 505;

int n, m, u, v, in[N], cop[N];
vector<int> G[N], ans;

bool tsort()
{
	ans.clear();
	queue<int> q;
	for (int i = 1; i <= n; i++)
	{
		cop[i] = in[i];
		if (cop[i] == 0) q.push(i);
	}
	while (!q.empty())
	{
		int l = q.front();
		q.pop();
		ans.push_back(l);
		for (int i = 0; i < G[l].size(); i++)
		{
			int nx = G[l][i];
			cop[nx]--;
			if (cop[nx] == 0) q.push(nx);
		}
	}
	return ans.size() == n;
}

int main()
{
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++)
	{
		scanf("%d %d", &u, &v);
		G[u].push_back(v);
		in[v]++;
	}
	for (int i = 1; i <= n; i++)
	{
		if (in[i] > 0)
		{
			in[i]--;
			if (tsort()) 
			{
				printf("YES\n");
				return 0;
			}
			in[i]++;
		}
	}
	printf("NO\n");
	return 0;
}
posted @   HappyBobb  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示