1. 程式人生 > >CF 1027F Session in BSU (並查集+樹上構造)

CF 1027F Session in BSU (並查集+樹上構造)

考試 style fine ring head 發現 char nod getc

題目大意:你可以在第$ai$天或者第$bi$天進行第$i$場考試,每天最多進行一場考試,求把所有考試都考完的最早結束時間

由於天數可能很大,需要離散

把問題抽象成一棵樹,每個點最多被"分配"一條邊,現在要刪點

畫畫圖可以發現

如果一個聯通塊是一棵樹,那麽可以刪去至多一個點

如果一個聯通塊是一個單環樹(n個點n條邊),那麽一個點都不能刪掉

如果一個聯通塊邊數大於點數,會發現無法把每個點只分配一條邊,不合法,輸出-1

判樹還是單環樹,求一個聯通塊內點的度總和/2和點數比較即可

並查集維護一下點屬於哪個聯通塊即可

註意點數是$2*10^6$而不是$1*10^6$

 1 #include <queue>
 2
#include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N 2000100 6 #define maxn 100000 7 #define ll long long 8 #define mod 1000000007 9 #define iset multiset<node>::iterator 10 using namespace std; 11 //re 12 int gint() 13 { 14 int ret=0,fh=1;char c=getchar(); 15 while
(c<0||c>9){if(c==-)fh=-1;c=getchar();} 16 while(c>=0&c<=9){ret=ret*10+c-0;c=getchar();} 17 return ret*fh; 18 } 19 int n,m,K,ma,cte,num; 20 int head[N],inc[N],id[N*2],vis[N],fa[N],sum[N],sz[N],typ[N]; 21 struct E{int x,y;}e[N]; 22 struct Edge{int to,nxt,val;}edge[N*2];
23 void ae(int u,int v){ 24 cte++;edge[cte].to=v,inc[v]++; 25 edge[cte].nxt=head[u],head[u]=cte;} 26 int find_fa(int x){ 27 int y=x,pre;while(fa[y]!=y){y=fa[y];} 28 while(fa[x]!=y){pre=fa[x],fa[x]=y,x=pre;} 29 return y; 30 } 31 int dfs(int u) 32 { 33 vis[u]=1;int ans=1; 34 for(int j=head[u];j;j=edge[j].nxt){ 35 int v=edge[j].to; 36 if(vis[v]) continue; 37 fa[v]=u,ans+=dfs(v),sz[u]+=sz[v]; 38 }sz[u]+=inc[u];return ans; 39 } 40 41 int main() 42 { 43 scanf("%d",&n); 44 int x,y,z,fx; 45 for(int i=1;i<=n;i++) 46 e[i].x=gint(),e[i].y=gint(), 47 id[++num]=e[i].x,id[++num]=e[i].y; 48 sort(id+1,id+num+1); 49 num=unique(id+1,id+num+1)-(id+1); 50 for(int i=1;i<=n;i++){ 51 x=lower_bound(id+1,id+num+1,e[i].x)-id; 52 y=lower_bound(id+1,id+num+1,e[i].y)-id; 53 ae(x,y),ae(y,x); 54 }int tot; 55 for(int i=1;i<=num;i++) fa[i]=i; 56 for(int i=1;i<=num;i++) 57 if(!vis[i]){ 58 sum[i]=dfs(i); 59 if(sum[i]==(sz[i]+2)/2) 60 typ[i]=1; 61 else if(sum[i]==(sz[i]/2)) 62 typ[i]=0; 63 else{printf("-1\n");return 0;} 64 } 65 int ans=num; 66 for(int i=num;i>=1;i--){ 67 fx=find_fa(i); 68 if(typ[fx]==1) {typ[fx]=0;ans=i-1;} 69 else break; 70 } 71 printf("%d\n",id[ans]); 72 return 0; 73 }

CF 1027F Session in BSU (並查集+樹上構造)