【CF1027F】Session in BSU(dsu,基环树)

题意:给出n场考试,每场考试有2天可以通过(第aibi天)。每天最多参加一场考试,现在要求所有考试全部通过的最小天数

n<=1e6,1<=a[i]<b[i]<1e9

思路:From https://blog.csdn.net/qq_34454069/article/details/81835772

维护块内最大值,次大值,点数,边数

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<string>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<map>
  8 #include<set>
  9 #include<queue>
 10 #include<vector>
 11 #include<bitset>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef unsigned int uint;
 15 typedef unsigned long long ull;
 16 typedef pair<int,int> PII;
 17 typedef vector<int> VI;
 18 #define fi first
 19 #define se second 
 20 #define MP make_pair
 21 #define mem0(a) memset(a,0,sizeof(a))
 22 #define N      2100000
 23 #define M      51
 24 #define MOD 998244353
 25 #define eps 1e-8 
 26 #define pi     acos(-1)
 27 #define oo     1e9
 28 
 29 struct node
 30 {
 31     int x,y;
 32 }a[N];
 33 
 34 int s[N][2],b[N],f[N],g[N],v[N],Data[N],c[N];
 35 
 36 void prepare(int *x,int n) 
 37 {
 38     for(int i=1;i<=n;i++) Data[i]=x[i];
 39     sort(Data+1,Data+n+1);    
 40     int m=unique(Data+1,Data+n+1)-Data-1;
 41     for(int i=1;i<=n;i++) x[i]=lower_bound(Data+1,Data+m+1,x[i])-Data;
 42 }
 43 
 44 int find(int k)
 45 {
 46     if(f[k]!=k) f[k]=find(f[k]);
 47     return f[k];
 48 }
 49 
 50 int main()
 51 {
 52     int n;
 53     scanf("%d",&n);
 54     int m=0; 
 55     for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y); 
 56     for(int i=1;i<=n;i++) b[++m]=a[i].x;
 57     for(int i=1;i<=n;i++) b[++m]=a[i].y;
 58     prepare(b,m);
 59     for(int i=1;i<=n;i++) 
 60     {
 61         c[b[i]]=a[i].x;
 62         c[b[i+n]]=a[i].y;
 63         a[i].x=b[i];
 64         a[i].y=b[i+n];
 65     } 
 66     int id=0;
 67     for(int i=1;i<=m;i++) id=max(id,b[i]); 
 68     for(int i=1;i<=id;i++) 
 69     {
 70         f[i]=i;
 71         g[i]=0;
 72         v[i]=1;
 73         s[i][0]=i;
 74         s[i][1]=-1;
 75     }
 76     for(int i=1;i<=n;i++)
 77     { 
 78         int x=find(a[i].x);
 79         int y=find(a[i].y);
 80         if(x!=y)
 81         {
 82             f[x]=y;
 83             g[y]=g[x]+g[y]+1;
 84             v[y]=v[x]+v[y];
 85             if(s[x][1]>s[y][1])
 86             {
 87                 s[y][1]=s[x][1];
 88                 if(s[y][1]>s[y][0]) swap(s[y][1],s[y][0]);
 89             }
 90             if(s[x][0]>s[y][1])
 91             {
 92                 s[y][1]=s[x][0];
 93                 if(s[y][1]>s[y][0]) swap(s[y][1],s[y][0]);
 94             }    
 95         }
 96          else g[x]++;
 97     }
 98     int ans=-1;
 99     for(int i=1;i<=id;i++)
100     {
101         if(v[i]==g[i]+1) ans=max(ans,s[i][1]);
102          else if(v[i]==g[i]) ans=max(ans,s[i][0]);
103           else 
104           {
105             ans=-1;
106             break;
107           }
108     }    
109     if(ans!=-1) printf("%d\n",c[ans]);
110      else printf("-1\n"); 
111     return 0;
112 }

猜你喜欢

转载自www.cnblogs.com/myx12345/p/10108674.html