zoukankan      html  css  js  c++  java
  • BZOJ NOI十连测 第二测 T1

    出题人居然是个哲学家。。

    26%的程序,太SB了。。。本来我的想法也是二分+贪心,但是贪心是个怪怪的SX贪心。。

      1 #include<algorithm>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<time.h>
      7 #define inf 0x7fffffff
      8 struct edge{
      9     int u,v,id;
     10 }e[400005];
     11 int tot,go[400005],first[200005],next[400005];
     12 int Tot,Go[400005],First[200005],Next[400005];
     13 int c[200005],b[200005],son[200005],ans,vis[200005],pd;
     14 int pass[400005],op[400005],C[400005],Cnt,block,sum,B[200005];
     15 int id1,id2;
     16 int n,k;
     17 int read(){
     18     char ch=getchar();int t=0,f=1;
     19     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
     20     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
     21     return t*f;
     22 }
     23 void Dfs(int x,int fa){
     24     if (vis[x]) return;
     25     c[x]=b[x];son[x]=1;
     26     for (int i=first[x];i;i=next[i]){
     27         int pur=go[i];
     28         if (pur==fa) continue;
     29         if (pass[i]) continue;
     30         Dfs(pur,x);
     31         son[x]+=son[pur];
     32         c[x]+=c[pur];
     33     }
     34     if (c[x]&&(n-c[x]>0)) ans=std::min(ans,std::max(son[x],n-son[x]));
     35 }
     36 void sbpianfen(){
     37     ans=inf;
     38     Dfs(1,0);
     39     printf("%d
    ",ans);
     40 }
     41 void insert(int x,int y){
     42     tot++;
     43     go[tot]=y;
     44     next[tot]=first[x];
     45     first[x]=tot;
     46     pass[tot]=1;
     47 }
     48 void add(int x,int y){
     49     insert(x,y);op[tot]=tot+1;insert(y,x);op[tot]=tot-1;
     50 }
     51 void Insert(int x,int y){
     52     Tot++;
     53     Go[Tot]=y;
     54     Next[Tot]=First[x];
     55     First[x]=Tot;
     56 }
     57 void Add(int x,int y){
     58     Insert(x,y);Insert(y,x);
     59 }
     60 int bfs(int x){
     61     int h=1,t=1;
     62     bool ck=0;
     63     c[1]=x;vis[x]=1;if (b[x]) ck=1;
     64     while (h<=t){
     65         int now=c[h++];
     66         for (int i=First[now];i;i=Next[i]){
     67             int pur=Go[i];
     68             if (vis[pur]) continue;
     69             c[++t]=pur;
     70             vis[pur]=1;
     71             if (b[pur]) ck=1;
     72         }
     73     }
     74     if (!ck) pd=1;
     75     return t;
     76 }
     77 void dFs(int x){
     78     if (x==n){
     79         pd=0;
     80         int bl=0;
     81         for (int i=1;i<=n;i++)
     82          First[i]=0;
     83         Tot=0; 
     84         for (int i=1;i<n;i++)
     85          if (!e[i].id) Add(e[i].u,e[i].v);
     86         for (int i=1;i<=n;i++)
     87           vis[i]=0;
     88         for (int i=1;i<=n;i++)
     89          if (!vis[i])
     90           bl=std::max(bl,bfs(i));
     91         if (pd==0) ans=std::min(ans,bl);     
     92         return;
     93     }
     94     e[x].id=1;
     95     dFs(x+1);
     96     e[x].id=0;
     97     dFs(x+1);
     98 }
     99 void sxpianfen(){
    100     for (int i=1;i<n;i++) e[i].id=0;
    101     dFs(1);
    102 }
    103 void clear(int x){
    104     int h=1,t=1;
    105     C[1]=x;
    106     bool ppp=1;
    107     if (b[x]) Cnt++,ppp=0;
    108     vis[x]=1;b[x]=0;
    109     while (h<=t){
    110         int now=C[h++];
    111         for (int i=first[now];i;i=next[i]){
    112             int pur=go[i];
    113             if (pass[i]) continue;
    114             if (vis[pur]) continue;
    115             C[++t]=pur;
    116             vis[pur]=1;
    117             if (b[pur]) Cnt++,ppp=0;
    118             b[pur]=0;
    119         }
    120     }
    121     if (ppp) {
    122         pd=1;
    123         return;
    124     }
    125     if (t>block) pd=1;
    126     sum-=t;
    127 }
    128 void work(int x,int mid,int fa,int Edge){
    129     if (c[x]==1&&b[fa]==1&&son[x]<=block) {
    130         pass[Edge]=1;
    131         pass[op[Edge]]=1;
    132         clear(x);
    133         id1=x;id2=fa;
    134         if (pd) return;
    135         return;
    136     }
    137     else
    138     if (k-Cnt-c[x]==1&&b[x]==1&&sum-son[x]<=block){
    139         pass[Edge]=1;
    140         pass[op[Edge]]=1;
    141         clear(fa);
    142         id1=x;id2=fa;
    143         if (pd) return;
    144         return;
    145     }
    146     else
    147     if (c[x]==1&&son[x]<=block&&son[fa]>=block){
    148         pass[Edge]=1;
    149         pass[op[Edge]]=1;
    150         clear(x);
    151         id1=x;id2=fa;
    152         if (pd) return;
    153         return;
    154     }else
    155     if (k-Cnt-c[x]==1&&sum-son[x]==block){
    156         pass[Edge]=1;
    157         pass[op[Edge]]=1;
    158         clear(fa);
    159         id1=x;id2=fa;
    160         if (pd) return;
    161         return;
    162     }
    163     for (int i=first[x];i;i=next[i]){
    164         int pur=go[i];
    165         if (pur==fa) continue;
    166         if (vis[pur]) continue;
    167         if (pass[i]) continue;
    168         work(pur,mid,x,i);
    169     }
    170 }
    171 bool check(int mid){
    172     for (int i=1;i<n;i++) std::swap(e[rand()%(n-1)+1],e[rand()%(n-1)+1]);
    173     for (int i=1;i<=n;i++) first[i]=0;
    174     tot=0;
    175     for (int i=1;i<n;i++)
    176      add(e[i].u,e[i].v);
    177     block=mid;pd=0;
    178     for (int i=1;i<=tot;i++)
    179      pass[i]=0;
    180     for (int i=1;i<=n;i++)
    181      b[i]=B[i],vis[i]=0;
    182     id1=1;id2=0;vis[0]=1;
    183     sum=n;Cnt=0;
    184     for (int i=1;i<=k;i++){
    185       if (vis[id1]&&vis[id2]) break;
    186       if (k-Cnt==1) break;
    187       if (!vis[id1]){
    188        Dfs(id1,0);
    189        work(id1,mid,0,0);
    190       }else{
    191        Dfs(id2,0);
    192        work(id2,mid,0,0);    
    193       }
    194       if (pd) return 0;
    195     }  
    196     for (int i=1;i<=n;i++)
    197      if (!vis[i]) clear(i);
    198     if (pd) return 0; 
    199     return 1; 
    200 }
    201 void solve(){
    202     int l=n/k,r=n,Ans=n;
    203     while (l<=r){
    204         int mid=(l+r)/2;
    205         if (check(mid)) r=mid-1,Ans=mid;
    206         else l=mid+1;
    207     }
    208     printf("%d
    ",Ans);
    209 }
    210 void solve2(){
    211     int l=n/k,r=n,Ans=n;
    212     while (l<=r){
    213         int mid=(l+r)/2;
    214         if (check(mid)) r=mid-1,Ans=mid;
    215         else l=mid+1;
    216     }
    217     int Tn=Ans;
    218     l=n/k,r=n,Ans=n;
    219     while (l<=r){
    220         int mid=(l+r)/2;
    221         if (check(mid)) r=mid-1,Ans=mid;
    222         else l=mid+1;
    223     }
    224     Tn=std::min(Tn,Ans);
    225     printf("%d
    ",Tn);
    226 }
    227 int main(){
    228     //
    229     freopen("deep.in","r",stdin);
    230     freopen("deep.out","w",stdout);
    231     srand(time(NULL));
    232     ans=inf;
    233     n=read();k=read();
    234     for (int i=1;i<n;i++){
    235         int x=read(),y=read();
    236         add(x,y);
    237         e[i].u=x;e[i].v=y;
    238     }
    239     for (int i=1;i<=k;i++){
    240         int x=read();
    241         b[x]=1;B[x]=1;
    242     }
    243     if (n<=20) {sxpianfen();printf("%d
    ",ans);return 0;}
    244     if (k==1) {printf("%d
    ",n);return 0;}
    245     if (k==2) {sbpianfen();return 0;}
    246     if (n<=2000) {solve();return 0;}
    247     if (k==3) {solve2();return 0;}
    248     if (k==n) {printf("%d
    ",1);return 0;}
    249     if (k==n-1) {printf("%d
    ",2);return 0;}
    250     solve();
    251 }

    AC程序不知道短到哪里去了

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 #define N 200005
     7 int tot,go[N*2],next[N*2],first[N];
     8 int n,k,b[N],fa[N],mx[N],sum[N],vis[N],c[N];
     9 int read(){
    10     char ch=getchar();int t=0,f=1;
    11     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    12     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    13     return t*f;
    14 }
    15 void insert(int x,int y){
    16     tot++;
    17     go[tot]=y;
    18     next[tot]=first[x];
    19     first[x]=tot;
    20 }
    21 void add(int x,int y){
    22     insert(x,y);insert(y,x);
    23 }
    24 void bfs(){
    25     int h=1,t=1;for (int i=1;i<=n;i++) vis[i]=0;
    26     c[1]=1;
    27     vis[1]=1;
    28     while (h<=t){
    29         int now=c[h++];
    30         for (int i=first[now];i;i=next[i]){
    31             int pur=go[i];
    32             if (vis[pur]) continue;
    33             vis[pur]=1;
    34             c[++t]=pur;
    35             fa[pur]=now;
    36         }
    37     }
    38 }
    39 bool check(int mid){
    40     int f;
    41     memset(sum,0,sizeof sum);
    42     memset(mx,0,sizeof mx);
    43     for (int i=n;i>=1;i--){
    44         int u=c[i];
    45         if (b[u]) mx[u]=mid-1;
    46         else sum[u]++;
    47         f=(mx[u]>=sum[u])?mx[u]-sum[u]:-sum[u];
    48         if (u==1&&f<0) return 0;
    49         if (f<0) sum[fa[u]]-=f;
    50         else mx[fa[u]]=std::max(mx[fa[u]],f);
    51     }
    52     return 1;
    53 }
    54 int main(){
    55     n=read();k=read();
    56     for (int i=1;i<n;i++){
    57         int x=read(),y=read();
    58         add(x,y);
    59     }
    60     for (int i=1;i<=k;i++){
    61         int x=read();
    62         b[x]=1;
    63     }
    64     bfs();
    65     int l=n/k,r=n,ans;
    66     while (l<=r){
    67         int mid=(l+r)>>1;
    68         if (check(mid)) r=mid-1,ans=mid;
    69         else l=mid+1;
    70     }
    71     printf("%d
    ",ans);
    72 }
  • 相关阅读:
    约瑟夫问题的解法集锦
    java调用com组件将office文件转换成pdf
    hdu(1069)——Monkey and Banana(LIS变形)
    Unix网络编程之环境搭建
    atitit. java queue 队列体系and自己定义基于数据库的队列总结o7t
    怎样使Dialog像Activity一样随心所欲的使用?
    获取全部分组中某列最大的行
    Class C++
    spring mvc +Mybatis3.1 整合的时候异常
    Linux 编译C++ 与 设置 Vim
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5590993.html
Copyright © 2011-2022 走看看