E. Monkeys ###K //K

题目链接:https://codeforces.ml/edu/course/2/lesson/7/1/practice/contest/289390/problem/E

题意:第一只猴子的 尾巴挂在树上 每只猴子的左右手可以抓住其他猴子的尾巴 给定某只猴子

松开某只手的时间 问每只猴子的掉落时间

思路:把删边转换成倒序加边  每次处理两堆集合的时候 如果其中没有根集合(即集合1) 那么就启发式合并
如果有根集合 就更新另一个集合的时间点为i 因为之后就不会再被更新了

  1 #include <bits/stdc++.h>
  2 #define ll long long
  3 #define pb push_back
  4 using namespace std;
  5 const int maxn=2e5+10;
  6 int f[maxn];
  7 int vis[maxn][3];
  8 vector<int>E[maxn];
  9  
 10  
 11 int find1(int x)
 12 {
 13     if(x==f[x])
 14         return x;
 15     return f[x]=find1(f[x]);
 16 }
 17  
 18 void add(int x,int y)
 19 {
 20     int t1=find1(x),t2=find1(y);
 21     f[t1]=t2;
 22 }
 23  
 24 struct ac
 25 {
 26     int l,r;
 27 };
 28 ac a[maxn],c[maxn*2];
 29 int ans[maxn];
 30  
 31  
 32  
 33 int main()
 34 {
 35     ios::sync_with_stdio(0);
 36     cin.tie(0);
 37     int n,m;
 38     cin>>n>>m;
 39     for(int i=1;i<=n;i++)
 40         f[i]=i;
 41     for(int i=1;i<=n;i++)
 42     {
 43         cin>>a[i].l>>a[i].r;
 44     }
 45     for(int i=1;i<=m;i++)
 46     {
 47         int l,r;
 48         cin>>l>>r;
 49         c[i].l=l,c[i].r=r;
 50         vis[l][r]=1;//l个人的r手
 51     }
 52     for(int i=1;i<=n;i++)
 53     {
 54         int l=a[i].l,r=a[i].r;
 55         if(l!=-1&&!vis[i][1])
 56             add(i,l);
 57         if(r!=-1&&!vis[i][2])
 58             add(i,r);
 59     }
 60     for(int i=1;i<=n;i++)
 61         ans[i]=-1;
 62     for(int i=1;i<=n;i++)
 63     {
 64         E[find1(i)].pb(i);
 65     }
 66     for(int i=m-1;i>=0;i--)
 67     {
 68         int p=c[i+1].l,h=c[i+1].r;
 69         int t1=find1(p);
 70         int t2;
 71         if(h==1)
 72             t2=find1(a[p].l);
 73         else
 74             t2=find1(a[p].r);
 75         if(t1!=t2)
 76         {
 77             if(t1==find1(1))
 78             {
 79                 f[t2]=t1;
 80                 for(auto &v:E[t2])
 81                     ans[v]=i;
 82                 continue;
 83             }
 84             if(t2==find1(1))
 85             {
 86                 f[t1]=t2;
 87                 for(auto &v:E[t1])
 88                     ans[v]=i;
 89                 continue;
 90             }
 91             if(E[t1].size()>E[t2].size())
 92                 swap(t1,t2);
 93             f[t1]=t2;
 94             for(auto &v:E[t1])
 95             {
 96                 E[t2].pb(v);
 97             }
 98         }
 99     }
100     for(int i=1;i<=n;i++)
101         cout<<ans[i]<<'\n';
102  
103  
104  
105  
106 }
View Code

 

posted @ 2020-12-14 16:14  canwinfor  阅读(138)  评论(0)    收藏  举报