• CF1027F 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 }
  • 相关阅读:
    使用RazorGenerator对视图View进行单元测试
    C#常用获取本周、本月、本季度、本年的时间起止段代码
    Redis使用记录
    Git和ConEmu
    mongodb单索引的升序和降序
    AES 加密解密 php c#
    redis 外网连接错误
    .net mvc 分页
    检查Windows上安装的.net版本
    sqlserver跨服务器查询
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9841106.html
Copyright © 2020-2023  润新知