zoukankan      html  css  js  c++  java
  • [loj2477]劈配

    考虑依次选择每一位考生,设当前选到第$i+1$位,前i个分别为$p1,p2,……pi$(注意:这里只确定了导师的志愿编号),然后枚举第$p_{i+1}$,通过网络流建图+判定,复杂度为$o(nm*f(n+m,cn))$($f(n,m)$表示点数为n、边数为m的网络流),无法通过
    考虑优化,由于网络流可以先任意流,那么直接在之前的残余网络上加上第k份志愿并判断能否联通即可,复杂度$o(cn^{2}m)$
    第二个问题类似,存储下每一次跑完后的残余网络,然后从下往上枚举其排名(志愿为si及其以上的)并建图,复杂度同样为$o(cn^{2}m)$
     
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 205
     4 struct ji{
     5     int nex,to,len;
     6 }edge[30*N],e[N][30*N];
     7 vector<int>v[N][N];
     8 int E,t,n,m,x,EE[N],head[N<<1],vis[N<<1],h[N][N<<1];
     9 void add(int x,int y,int z){
    10     edge[E].nex=head[x];
    11     edge[E].to=y;
    12     edge[E].len=z;
    13     head[x]=E++;
    14 }
    15 bool dfs(int k){
    16     if (k==n+m+1)return 1;
    17     if (vis[k])return 0;
    18     vis[k]=1;
    19     for(int i=head[k];i!=-1;i=edge[i].nex)
    20         if ((edge[i].len)&&(dfs(edge[i].to))){
    21             edge[i].len--;
    22             edge[i^1].len++;
    23             return 1;
    24         }
    25     return 0;
    26 }
    27 int main(){
    28     scanf("%d%*d",&t);
    29     while (t--){
    30         scanf("%d%d",&n,&m);
    31         E=0;
    32         memset(head,-1,sizeof(head));
    33         for(int i=1;i<=n;i++)
    34             for(int j=1;j<=m;j++)v[i][j].clear();
    35         for(int i=1;i<=m;i++){
    36             scanf("%d",&x);
    37             add(i+n,n+m+1,x);
    38             add(n+m+1,i+n,0);
    39         }
    40         for(int i=1;i<=n;i++)
    41             for(int j=1;j<=m;j++){
    42                 scanf("%d",&x);
    43                 if (x)v[i][x].push_back(j);
    44             }
    45         EE[0]=E;
    46         memcpy(h[0],head,sizeof(head));
    47         memcpy(e[0],edge,sizeof(edge));
    48         for(int i=1;i<=n;i++){
    49             bool flag=0;
    50             EE[i]=E;
    51             memcpy(h[i],head,sizeof(head));
    52             memcpy(e[i],edge,sizeof(edge));
    53             for(int j=1;j<=m;j++){
    54                 E=EE[i];
    55                 memset(vis,0,sizeof(vis)); 
    56                 memcpy(head,h[i],sizeof(head));
    57                 memcpy(edge,e[i],sizeof(edge));
    58                 for(int k=0;k<v[i][j].size();k++){
    59                     add(i,v[i][j][k]+n,1);
    60                     add(v[i][j][k]+n,i,0);
    61                 }
    62                 if (dfs(i)){
    63                     flag=1;
    64                     printf("%d ",j);
    65                     break;
    66                 }
    67             }
    68             if (!flag)printf("%d ",m+1);
    69             EE[i]=E;
    70             memcpy(h[i],head,sizeof(head));
    71             memcpy(e[i],edge,sizeof(edge));
    72         }
    73         printf("
    ");
    74         for(int i=1;i<=n;i++){
    75             scanf("%d",&x);
    76             bool flag=0;
    77             for(int j=i;j;j--){
    78                 E=EE[j-1];
    79                 memset(vis,0,sizeof(vis)); 
    80                 memcpy(head,h[j-1],sizeof(head));
    81                 memcpy(edge,e[j-1],sizeof(edge));
    82                 for(int k=1;k<=x;k++)
    83                     for(int l=0;l<v[i][k].size();l++){
    84                         add(i,v[i][k][l]+n,1);
    85                         add(v[i][k][l]+n,i,0);
    86                     }
    87                 if (dfs(i)){
    88                     flag=1;
    89                     printf("%d ",i-j);
    90                     break;
    91                 }
    92             }
    93             if (!flag)printf("%d ",i);
    94         }
    95         printf("
    ");
    96     }
    97 }
    View Code
  • 相关阅读:
    我理解的优秀软件工程师
    Hello 博客园!
    线程安全与可重入函数之间的区别与联系
    linux-粘滞位的使用
    死锁产生的四个必要条件及处理死锁的策略
    数据结构—位图
    Linux下进度条的简单实现
    Linux-find命令
    Linux文件3个时间点(access time,modify time,change time)
    各种排序算法的实现、总结
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/12932505.html
Copyright © 2011-2022 走看看