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;
}