gym102059 Electronic Circuit

本文探讨了在编程竞赛中使用博弈论和SG函数解决特定问题的方法。通过实例解析,阐述了如何利用度为二的点简化图结构,并通过set数据结构去除重复边,最终判断是否存在可行解。文章提供了详细的C++代码实现。

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

https://codeforces.com/gym/102059/problem/E

被签到博弈关了一下午,队内博弈选手没来,sg函数都是我18年1月学的东西了,早忘光了。。。。

结果看了这题发现全机房都做出来了我也不会做,菜哭.jpg

很简单的思路,就是度为二的点可以被去掉,a-u-b可以等价为a-b,不断重复这个过程到最后只剩一对点和一条边或者不剩点就结束了,用set对重复边去重,重边都是可以并联的,串联就是不断合并的过程

#include<bits/stdc++.h>
#define maxl 100010
#define mkp make_pair
using namespace std;
 
int n,m,ans;
typedef pair<int,int> p;
set <p> s[maxl];
queue <int> q;
bool in[maxl];
 
inline void prework()
{
	scanf("%d%d",&n,&m);
	int x,y;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		s[x].insert(mkp(x,y));
		s[y].insert(mkp(y,x));
	}
}
 
inline void mainwork()
{
	for(int i=1;i<=n;i++)
	if((int)s[i].size()==2)
	{ 
		q.push(i);
		in[i]=true; 
	} 
	int u,a,b;
	while(!q.empty())
	{
		u=q.front();q.pop();
		if(s[u].begin()==s[u].end())
			continue;
		a=(*s[u].begin()).second;
		b=(*s[u].rbegin()).second;
		if(a==b)
			continue;
		if(s[a].find(mkp(a,u))!=s[a].end())
		{
			s[a].erase(s[a].find(mkp(a,u)));
			s[a].insert(mkp(a,b));
		}
		if(s[b].find(mkp(b,u))!=s[b].end())
		{
			s[b].erase(s[b].find(mkp(b,u)));
			s[b].insert(mkp(b,a));
		}
		if((int)s[a].size()==2 && !in[a])
		{
			q.push(a);
			in[a]=true;
		}
		if((int)s[b].size()==2 && !in[b])
		{	
			q.push(b);
			in[b]=true;
		}
	}
	u=0;a=0;b=0;
	for(int i=1;i<=n;i++)
	if(!in[i])
	{
		if(!a) a=i;
		else if(!b) b=i;
		u++;
	}
	if(u==0)
	{
		ans=1;
		return;
	}
	if(u==2 && (int)s[a].size()==1 && (int)s[b].size()==1 &&
		(*s[a].begin()).second==b && (*s[b].begin()).second==a)
		ans=1;
	else
		ans=0;
}
 
inline void print()
{
	if(ans)
		puts("Yes");
	else
		puts("No");
}
 
int main()
{
	prework();
	mainwork();
	print();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值