1. 程式人生 > >【CF1027F】Session in BSU(dsu,基環樹)

【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 }