整体来说,这一场的质量比较高,但是题意也有些难懂。
E.Electronic Circuit
题意: 给你N个点,M根线,问它是否是一个合法的电路。
思路: 一个合法的电路,经过一些串联并联关系,最后有一个点是正极,一个是负极,我们就来模拟这个串联的过程即可,并联的关系会因为我们使用了set而抵消,所以可以不去管它。 模拟串联: 我们选择一个度数为2的点,删去它与两边的点u,v的连线,然后连接u-v,知道不存在度数为2的点。 最后当有两个点度数为1,而且不存在度数为大于大于2的点,则合法。
(选择set其实比较巧妙,因为不用考虑并联。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=100010; set<int>S[maxn]; queue<int>q; int main() { int N,M,u,x,y; scanf("%d%d",&N,&M); rep(i,1,M){ scanf("%d%d",&x,&y); S[x].insert(y); S[y].insert(x); } rep(i,1,N) if(S[i].size()==2) q.push(i); while(!q.empty()){ u=q.front(); q.pop(); if(S[u].size()!=2) continue; x=*S[u].begin(); S[u].erase(S[u].begin()); y=*S[u].begin(); S[u].erase(S[u].begin()); S[x].erase(u); S[y].erase(u); S[x].insert(y); S[y].insert(x); if(S[x].size()==2) q.push(x); if(S[y].size()==2) q.push(y); } int cnt=0,ok=1; rep(i,1,N) { if(S[i].size()==1) cnt++; if(S[i].size()>1) ok=0; } if(ok&&cnt==2) puts("Yes"); else puts("No"); return 0; }