CF 1027F Session in BSU (并查集+树上构造)

Posted guapisolo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF 1027F Session in BSU (并查集+树上构造)相关的知识,希望对你有一定的参考价值。

题目大意:你可以在第$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
");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
",id[ans]);
72     return 0;
73 }

 

以上是关于CF 1027F Session in BSU (并查集+树上构造)的主要内容,如果未能解决你的问题,请参考以下文章

Session in BSU CodeForces - 1027F(思维 树 基环树 离散化)

CF.1027F.Session in BSU(思路 并查集)

[Codeforces Round49F] Session in BSU

Codeforces 1027F. Session in BSU

[Codeforces 1027 F] Session in BSU [并查集维护二分图匹配问题]

Sessions in BSU