zoukankan      html  css  js  c++  java
  • 劈配 [多省省选] [BZOJ5251] [网络流]

    题目链接

    分析:

    这道题看题都看了我好久...

    我们可以容易想到这道题和网络流有关。

    首先,从原点向每个学员连一条流量为1的边

    然后,要限制每个导师的学员,在每个导师连到汇点的时候流量限制为bi

    再接着,按照学员的顺序一个个动态加边,一次性加入同样优先级的边,如果有增广路就记录答案。

    (第一问完美解决)

    然后第二问怎么做呢?

    对于一个学员,如果已经确定了排位,那我们很容易的就能验证是不是满足他的要求。

    那么我们就能在[1,i-1]的区间里二分答案去检验,在[1,now-1]的残余网络里面跑即可(注意加上他自己要求范围内的边)

    如何优化?

    第一问:如果把整个网络都加进去的话边数太多很可能会T,而我们发现有很多边是没用的->不能提供增广路的边

    那我们在跑完一个优先级发现找不到增广路的时候就把这些边全掉。

    第二问:显然,二分答案每次都建立残余网络是一个很大的工程,我们可以在第一问依次处理时把残余网络图给下来,第二问直接用即可。

    Code

      1 #include<bits/stdc++.h>
      2 #define RG register int
      3 #define rep(i,a,b)    for(RG i=a;i<=b;++i)
      4 #define per(i,a,b)    for(RG i=a;i>=b;--i)
      5 #define ll long long
      6 #define inf (1<<29)
      7 #define maxn 210
      8 #define maxm 10010
      9 using namespace std;
     10 int p,c,n,m,cnt,S,T;
     11 int tmph[maxn][maxn<<1],head[maxn<<1],hd[maxn<<1],step[maxn<<1],ans[maxn],cntt[maxn];
     12 int a[maxn][maxn],Ex[maxn],lmp[maxn][maxn],level[maxn],deal[maxn][maxn][12];
     13 struct E{
     14     int u,v,next,pre,fl;
     15 }e[maxm],tmpe[maxn][maxm];
     16 
     17 inline int read()
     18 {
     19     int x=0,f=1;char c=getchar();
     20     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     21     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     22     return x*f;
     23 }
     24 
     25 void init()
     26 {
     27     memset(lmp,0,sizeof(lmp));
     28     memset(head,0,sizeof(head));
     29     cnt=1;
     30 }
     31 
     32 inline void del(int i)
     33 {
     34     if(e[i].next)    e[e[i].next].pre=e[i].pre;
     35     if(e[i].pre)    e[e[i].pre].next=e[i].next;
     36     if(i==head[e[i].u]) head[e[i].u]=e[i].next;
     37 }
     38 
     39 inline void add(int u,int v,int w)
     40 {
     41     e[++cnt].v=v,e[cnt].u=u,e[cnt].next=head[u];
     42     if(head[u]) e[head[u]].pre=cnt;
     43     head[u]=cnt,e[cnt].fl=w;
     44     
     45     swap(u,v);
     46     
     47     e[++cnt].v=v,e[cnt].u=u,e[cnt].next=head[u];
     48     if(head[u]) e[head[u]].pre=cnt;
     49     head[u]=cnt,e[cnt].fl=0;
     50 }
     51 
     52 inline void add2(int u,int v,int w)
     53 {
     54     e[++cnt].v=v,e[cnt].next=head[u],head[u]=cnt,e[cnt].fl=w;    swap(u,v);
     55     e[++cnt].v=v,e[cnt].next=head[u],head[u]=cnt,e[cnt].fl=0;
     56 }
     57 
     58 bool bfs()
     59 {
     60     queue<int> que;
     61     memset(step,0,(T<<2)+5);memcpy(hd,head,(T<<2)+5);
     62     que.push(S),step[S]=1;
     63     RG u,v;
     64     while(!que.empty())
     65     {
     66         u=que.front(),que.pop();
     67         for(RG i=head[u];i;i=e[i].next)
     68         {
     69             v=e[i].v;
     70             if(e[i].fl&&!step[v])    step[v]=step[u]+1,que.push(v);
     71         }
     72     }
     73     return step[T];
     74 }
     75 
     76 int dfs(int u,int fl)
     77 {
     78     if(u==T) return fl;
     79     int tp,tt=0;
     80     for(RG &i=hd[u];i;i=e[i].next){
     81         int v=e[i].v;
     82         if(e[i].fl&&step[v]==step[u]+1)
     83         {
     84             tp=dfs(e[i].v,min(e[i].fl,fl));
     85             tt+=tp;
     86             e[i].fl-=tp;
     87             e[i^1].fl+=tp;
     88             if(tt==fl) return tt;
     89         } 
     90     }
     91     if(tt!=fl) step[u]=-1;
     92     return tt;
     93 }
     94 
     95 void work1()
     96 {
     97     RG l;
     98     rep(i,1,n)
     99     {
    100         ans[i]=m+1,add(S,i,1);
    101         rep(j,1,m)
    102         {
    103             if(!lmp[i][j]) continue;
    104             l=cnt;
    105             rep(k,1,lmp[i][j])         add(i,deal[i][j][k]+n,1);
    106             if(bfs()&&dfs(S,inf))    {ans[i]=j;break;}
    107             else                    {rep(k,l,cnt) del(k);cnt=l;}
    108         }
    109         rep(j,1,T)        tmph[i][j]=head[j];
    110         rep(j,2,cnt)    tmpe[i][j]=e[j];
    111         cntt[i]=cnt;
    112     }
    113     rep(i,1,n) printf("%d ",ans[i]);puts("");
    114 }
    115 
    116 bool judge(int u,int w)
    117 {
    118     cnt=cntt[w-1];
    119     rep(i,1,T)        head[i]=tmph[w-1][i];
    120     rep(i,2,cnt)    e[i]=tmpe[w-1][i];
    121         
    122     add(S,u,1);
    123         
    124     rep(i,1,Ex[u])
    125     {
    126         if(!lmp[u][i]) continue;
    127         rep(j,1,lmp[u][i]) add2(u,deal[u][i][j]+n,1);
    128     }
    129     
    130     return (bfs()&&dfs(S,inf));
    131 }
    132 
    133 void input()
    134 {
    135     n=read(),m=read();
    136     S=n+m+1,T=n+m+2;
    137     rep(i,1,m)
    138     {
    139         level[i]=read();
    140         add(i+n,T,level[i]);
    141     }
    142     cntt[0]=cnt;
    143     rep(i,2,cnt)    tmpe[0][i]=e[i];
    144     rep(i,1,T)        tmph[0][i]=head[i];
    145     rep(i,1,n)    rep(j,1,m)
    146     {
    147         a[i][j]=read();    if(!a[i][j]) continue;
    148         deal[i][a[i][j]][++lmp[i][a[i][j]]] = j;
    149     }
    150     rep(i,1,n) Ex[i]=read();
    151 }
    152 
    153 void work2()
    154 {
    155     RG l,r,mid,ans2;
    156     rep(i,1,n)
    157     {
    158         if(ans[i]<=Ex[i]){printf("0 ");continue;}
    159         l=1,r=i-1,ans2=0;
    160         while(l<=r)
    161         {
    162             mid=l+r>>1;
    163             if(judge(i,mid))    ans2=mid,l=mid+1;
    164             else                r=mid-1;
    165         }
    166         printf("%d ",i-ans2);
    167     }
    168     puts("");
    169 }
    170 
    171 
    172 
    173 int main()
    174 {
    175     freopen("mentor.in","r",stdin);
    176     freopen("mentor.out","w",stdout);
    177     int TT,C;
    178     TT=read(),C=read();
    179     while(TT--)
    180     {
    181         init();
    182         input();
    183         work1();
    184         work2();
    185     }
    186     return 0;
    187 }
  • 相关阅读:
    python 3.x 不再提供raw_print()
    php中fileatim,filectime和filemtime函数的区别
    如何将文本以BLOB类型存入数据库并取出
    tomcat启动不了——Error initializing endpoint——java.net.BindException: Address already in use: JVM_Bind
    hdu 2188(巴什博弈入门 )
    hdu 2187(贪心)
    Sentinel数据处理工具包SNAP Python开发环境搭建
    conda 安装包命令
    使用SSH连接WSL
    win10 安装WSL 出现 WslRegisterDistribution failed with error: 0x8000000d
  • 原文地址:https://www.cnblogs.com/ibilllee/p/8762389.html
Copyright © 2011-2022 走看看