[atAGC014E]Blue and Red Tree

不断删除重边,然后将两个点的边集启发式合并(要考虑到两棵树),合并时发现重边就加入队列,最后判断是否全部删完即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 100005
 4 set<int>s[N];
 5 map<int,int>mat[N];
 6 queue<pair<int,int> >q;
 7 int n,x,y,ans,f[N];
 8 int find(int k){
 9     if (k==f[k])return k;
10     return f[k]=find(f[k]);
11 }
12 void add(int x,int y){
13     s[x].insert(y);
14     s[y].insert(x);
15     if (x>y)swap(x,y);
16     if (++mat[x][y]==2){
17         q.push(make_pair(x,y));
18         mat[x][y]=0;
19     }
20 }
21 void merge(int x,int y){
22     if (s[x].size()>s[y].size())swap(x,y);
23     f[x]=y;
24     for(set<int>::iterator it=s[x].begin();it!=s[x].end();it++){
25         int z=find(*it);
26         if (y==z)continue;
27         add(y,z);
28         s[z].erase(x);
29     }
30     s[x].clear();
31 }
32 int main(){
33     scanf("%d",&n);
34     for(int i=1;i<=n;i++)f[i]=i;
35     for(int i=1;i<2*n-1;i++){
36         scanf("%d%d",&x,&y);
37         add(x,y);
38     }
39     while (!q.empty()){
40         ans++;
41         merge(find(q.front().first),find(q.front().second));
42         q.pop();
43     }
44     if (ans==n-1)printf("YES");
45     else printf("NO");
46 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11356479.html