E-奇环(染色判断二分图+简单环判断)

E-奇环_牛客练习赛106 (nowcoder.com)

题目描述
有一张n个点的无向完全图,初始时任意两点间存在一条边(共"X(1)条边)。现从中删除m条边,删除的第i条边为ui,vi,判断删完这m条边的图中是否存在奇环。
。无向完全图:若无向简单图G中任意不同两点间均存在边相连,则称G为无向完全图。(无向简单图指没有重边和自环的无向图)
。奇环:指点的数量为奇数的简单环(简单环即没有重复边的环路)。关于简单环的定义可参考oi-wiki:图论相关概念-OI Wiki (oi-wiki.org)
输入描述:
第一行一个正整数1 第一行输入两个正整数1≤n ≤2×105,0≤m ≤ min(TX(-),2 ×10%),分别表示该无向完全图的点数、从该图中删除的边的数量。
接下来m 行,每行两个正整数1≤i,viSn,ui≠ v;以空格分隔,表示被删除的第i条边。保证输入没有重复的边。
保证对于T组测试数据,满足n≤2 ×105,m≤2×105。
输出描述:
对于每组测试数据,一行输出一个"YES”(不含引号)表示删完边的图中存在奇环,输出"NO”(不含引号)表示删完边的图中不存在奇环。
示例1

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

输入

复制3 3 0 4 2 1 3 2 4 4 2 1 2 1 3

3
3 0
4 2
1 3
2 4
4 2
1 2
1 3

输出

复制YES NO YES

YES
NO
YES

说明

第三组数据中,存在 2 - 3 - 4 - 2 这个大小为 3 的环,由于 3 是奇数,因此图中存在奇环。

题解:

。无向完全图:若无向简单图G中任意不同两点间均存在边相连,则称G为无向完全图。(无向简单图指没有重边和自环的无向图)
。奇环:指点的数量为奇数的简单环(简单环即没有重复边的环路)

根据给出的这两个条件,假设我们得到的是一个没有奇环的图,我们可以把他视为一个二分图

并分为左部和右部,设左部n1个点,右边n2个点,最多应该由n1*n2个点

应满足

n1 + n2  = n

n*(n-1)/2-m <= n1*n2

化简后得到m >= n*n/4 - n/2

所以如果不满足二分图m < n*n/4 - n/2

此时一定存在奇数环

再结合题中数据如果n >= 896时 结合m的范围一定不满足

所以但是如果n < 896时,数据就很小了,我们直接染色法找是否有奇环即可

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define int long long
vector p[1004];
bitset<20005> f[200005];
int st[200050];
int dfs(int x,int y)
{
	st[x] = y;
	for(auto k:p[x])
	{
		if(!st[k])
		{
			if(!dfs(k,3-y))
			{
				return 0;
			}
		}
		else if(st[k] == y)
		{
			return 0;
		}
	}
	return 1;
}
void solve() 
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);
//	cout.tie(0);
    int n,m;
    cin >> n>>m;
    if(m < n*n/4 - n/2)
    {
		cout<<"YES\n";
		return ;
	}
	for(int i = 1;i <= n;i++)
	{
		p[i].clear();
		f[i].reset();
		st[i] = 0;
	}
	for(int i = 1;i <= m;i++)
	{
		int l,r;
		cin >> l >>r;
		f[l][r] = f[r][l] = 1;
	}
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= n;j++)
		{
			if(i == j||f[i][j])
			continue;
			p[i].push_back(j);
		}
	}
	for(int i = 1;i <= n;i++)
	{
		if(!st[i])
		{
			if(!dfs(i,1))
			{
				cout<<"YES\n";
				return;
			}
		}
	}
	cout<<"NO\n";
}
signed main()
{
	int t = 1;
	cin >> t;
	while(t--)
	{
		solve();
	}
} 

你可能感兴趣的:(染色法,二分图)