整体来说,这一场的质量比较高,但是题意也有些难懂。

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

相关文章: