列表

详情


NC246841. 奇环

描述

有一张 n 个点的无向完全图,初始时任意两点间存在一条边(共 条边)。现从中删除 m 条边,删除的第 i 条边为 u_i, v_i,判断删完这 m 条边的图中是否存在奇环
  • 无向完全图:若无向简单图 G 中任意不同两点间均存在边相连,则称 G 为无向完全图。(无向简单图指没有重边和自环的无向图)
  • 奇环:指点的数量为奇数的简单环(简单环即没有重复边的环路)。
关于简单环的定义可参考 oi-wiki:图论相关概念 - OI Wiki (oi-wiki.org)

输入描述

第一行一个正整数  表示测试数据的组数,接下来 T 组测试数据:

第一行输入两个正整数 ,分别表示该无向完全图的点数、从该图中删除的边的数量。

接下来 m 行,每行两个正整数 以空格分隔,表示被删除的第 i 条边。保证输入没有重复的边。

保证对于 T 组测试数据,满足

输出描述

对于每组测试数据,一行输出一个 "YES" (不含引号)表示删完边的图中存在奇环,输出 "NO" (不含引号)表示删完边的图中不存在奇环。

示例1

输入:

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

输出:

YES
NO
YES

说明:

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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 79ms, 内存消耗: 16196K, 提交时间: 2022-12-02 20:42:47

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int i,j,k,n,m,t,f[2005][2005],g[2005],res;

void dfs(int x){
	//printf("NMSL%d %d\n",x,g[x]);
	for(int i=1;i<=n;i++){
		if(!f[x][i])continue;
		if(~g[i]){
			if(g[i]==g[x]){
				res=1;return;
			}
			continue;
		}
		g[i]=1-g[x];dfs(i);
	}
}

int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>t;
	while(t--){
		cin>>n>>m;
		if(n>=2000){
			for(i=1;i<=m;i++)cin>>j>>k;
			cout<<"YES\n";continue;
		}
		memset(f,1,sizeof(f));
		memset(g,-1,sizeof(g));
		for(i=1;i<=n;i++)f[i][i]=0;
		for(i=1;i<=m;i++){
			cin>>j>>k;
			f[j][k]=f[k][j]=0;
		}
		res=0;
		for(i=1;i<=n;i++){
			if(g[i]==-1){
				g[i]=0;dfs(i);
			}
			if(res)break;
		}
		if(res)cout<<"YES\n";
		else cout<<"NO\n";
	}
}

C++(clang++ 11.0.1) 解法, 执行用时: 78ms, 内存消耗: 10728K, 提交时间: 2022-12-02 20:05:59

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
const int N=2e5+10;
bool sb=0;
int vis[N];
vector<int> e[N];
int a=0,b=0;
void dfs(int x){
	vis[x]=1;
	b++;a+=e[x].size();
	for(auto v:e[x]){
		if(!vis[v]) dfs(v);
	}
}
void solve(){
	sb=0;
	int cnt=0;
	int n,m;cin>>n>>m;
	for(int i=1;i<=n;i++) vis[i]=0,e[i].clear();
	for(int i=1;i<=m;i++){
		int x,y;cin>>x>>y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			a=0;b=0;
			dfs(i);
			cnt++;
			if(a!=b*(b-1)) sb=1;
		}
	}
//	cout<<cnt<<" "<<sb<<endl;
	if(cnt==2&&!sb) cout<<"NO"<<endl;
	else cout<<"YES"<<endl;
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int T=1;
	cin>>T;
	while(T--) solve();
	return 0;
}

上一题