zoukankan      html  css  js  c++  java
  • 网络流+二分图模板

    最大流dinic(bzoj4873):

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 using namespace std;
      5 const int INF=0x3f3f3f3f;
      6 const int maxm=20001;
      7 struct node
      8 {
      9     int v,f,nex;
     10 }edge[maxm<<8];
     11 int head[maxm];
     12 int le[10085],tot=-1;
     13 int q[maxm];
     14 void add(int u,int v,int f)
     15 {
     16     edge[++tot]=(node){v,f,head[u]};
     17     head[u]=tot;
     18     edge[++tot]=(node){u,0,head[v]};
     19     head[v]=tot;
     20 }
     21 bool bfs(int s,int t)
     22 {
     23     memset(le,0,sizeof(le));
     24     le[s]=1;
     25     int fr=0,ta=1;
     26     q[fr]=s;
     27     while(fr<ta)
     28     {
     29         int x=q[fr++];
     30         if(x==t)    
     31             return true;
     32         for(int i=head[x];i!=-1;i=edge[i].nex)
     33         {
     34             int v=edge[i].v;
     35             int f=edge[i].f;
     36             if(!le[v]&&f)
     37             {
     38                 le[v]=le[x]+1;
     39                 q[ta++]=v;
     40             }
     41         }
     42     }
     43     return false;
     44 }
     45 int dfs(int u,int maxf,int t)
     46 {
     47     if(u==t)
     48         return maxf;
     49     int ret=0,v,f;
     50     for(int i=head[u];i!=-1;i=edge[i].nex)
     51     {
     52         v=edge[i].v;
     53         f=edge[i].f;
     54         if(le[u]+1==le[v]&&f)
     55         {
     56             int M=min(maxf-ret,f);
     57             f=dfs(v,M,t);
     58             edge[i].f-=f;
     59             edge[i^1].f+=f;
     60             ret+=f;
     61             if(ret==maxf)
     62                 return ret; 
     63         }
     64     }
     65     le[u]=0;
     66     return ret;
     67 }
     68 int dinic(int s,int t)
     69 {
     70     int ans=0;
     71     while(bfs(s,t))
     72         ans+=dfs(s,INF,t);
     73     return ans;
     74 }
     75 int id[101][101],idw[1001];
     76 int cnt=0;
     77 bool mark[1001];
     78 int S,T;
     79 int a[101],mp[101][101];
     80 long long sum;
     81 int n,m;
     82 void make()
     83 {
     84     S=0;
     85     for(int i=1;i<=n;i++)
     86         for(int j=i;j<=n;j++)
     87             id[i][j]=++cnt;
     88     for(int i=1;i<=n;i++)
     89         if(!mark[a[i]])
     90         {
     91             mark[a[i]]=true;
     92             idw[a[i]]=++cnt;    
     93         }
     94     T=cnt+n+1;  
     95     memset(mark,false,sizeof(mark));
     96     for(int i=1;i<=n;i++)
     97         if(!mark[a[i]])
     98         {
     99             mark[a[i]]=true;
    100             add(idw[a[i]],T,m*a[i]*a[i]);   
    101         }
    102     for(int i=1;i<=n;i++)
    103     {
    104         add(cnt+i,idw[a[i]],INF);
    105         add(cnt+i,T,a[i]);
    106     }
    107     for(int i=1;i<=n;i++)
    108     {
    109         for(int j=i;j<=n;j++)
    110         {
    111             if(mp[i][j]>0)
    112             {
    113                 sum+=mp[i][j];
    114                 add(S,id[i][j],mp[i][j]);
    115                 add(id[i][j],cnt+i,INF);
    116                 add(id[i][j],cnt+j,INF);
    117             }
    118             else
    119                 if(mp[i][j]<0)
    120                 {
    121                     add(id[i][j],T,-mp[i][j]);
    122                     add(id[i][j],cnt+i,INF);
    123                     add(id[i][j],cnt+j,INF);
    124                 }
    125             if(i!=j)
    126             {
    127                 add(id[i][j],id[i+1][j],INF);
    128                 add(id[i][j],id[i][j-1],INF);
    129             }
    130         }
    131     }
    132 }
    133 int main()
    134 {
    135     int x,y,z;
    136     scanf("%d%d",&n,&m);
    137     memset(head,-1,sizeof(head));
    138     for(int i=1;i<=n;i++)
    139         scanf("%d",&a[i]);
    140     for(int i=1;i<=n;i++)
    141         for(int j=i;j<=n;j++)
    142             scanf("%d",&mp[i][j]); 
    143     make();
    144     printf("%lld",sum-dinic(S,T));
    145     return 0;
    146 }
    dinic

    连续最短路(bzoj1877):

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 using namespace std;
      5 const int INF=0x7fffffff;
      6 const int maxn=201;
      7 const int maxm=20001;
      8 struct node
      9 {
     10     int v,f,w,nex;
     11 }edge[(maxn<<1)+(maxm<<1)];
     12 int pre[maxn<<1],tot=1;
     13 void add(int u,int v,int f,int w)
     14 {
     15     edge[++tot]=(node){v,f,w,pre[u]};
     16     pre[u]=tot;
     17     edge[++tot]=(node){u,0,-w,pre[v]};
     18     pre[v]=tot;
     19 }
     20 int q[(maxm<<3)+(maxm<<1)],d[maxn<<1];
     21 bool book[maxn<<1],mark[maxn<<1];
     22 int anst,ansl,head,tail;
     23 int n,m;
     24 int S,T;
     25 int len[maxn][maxn];
     26 bool spfa()
     27 {
     28     memset(book,false,sizeof(book));
     29     int i,x,v;
     30     for(i=0;i<=(n-1)*2;i++)
     31         d[i]=INF;
     32     head=0,tail=1;
     33     q[0]=T;
     34     d[T]=0;
     35     book[T]=true;
     36     while(head<tail)
     37     {
     38         x=q[head],head++;
     39         for(i=pre[x];i;i=edge[i].nex)
     40         {
     41             v=edge[i].v;
     42             if(edge[i^1].f&&d[x]-edge[i].w<d[v])
     43             {
     44                 d[v]=d[x]-edge[i].w;
     45                 if(!book[v])
     46                 {
     47                     q[tail++]=v;
     48                     book[v]=true;
     49                 }
     50             }
     51         }
     52         book[x]=false;
     53     }
     54     return d[S]!=INF;
     55 }
     56 int dfs(int x,int low)
     57 {
     58     mark[x]=1;
     59     if(x==T)
     60         return low;
     61     int v,i,w,u=0;
     62     for(i=pre[x];i;i=edge[i].nex)
     63     {
     64         v=edge[i].v;
     65         if(edge[i].f&&!mark[v]&&d[v]==d[x]-edge[i].w)
     66         {
     67             w=dfs(v,min(low-u,edge[i].f));
     68             ansl+=w*edge[i].w;
     69             u+=w;
     70             edge[i].f-=w;
     71             edge[i^1].f+=w;
     72             if(u==low)
     73                 return low;
     74         }
     75     }
     76     return u;
     77 }
     78 void zkw()
     79 {
     80     int tmp=0;
     81     while(spfa())
     82     {
     83         mark[T]=1;
     84         while(mark[T])
     85         {
     86             memset(mark,false,sizeof(mark));
     87             tmp+=dfs(S,INF);
     88         }
     89     }
     90     anst=tmp;
     91 }
     92 void make()
     93 {
     94     S=1;
     95     T=n;
     96     for(int i=2;i<=n-1;i++)
     97         add(i,i+n-1,1,0);
     98     for(int i=2;i<=n-1;i++)
     99         for(int j=1;j<=n;j++)
    100             if(len[i][j]!=0)
    101                 add(i+n-1,j,1,len[i][j]);
    102     for(int i=1;i<=n;i++)
    103         if(len[1][i]!=0)
    104             add(1,i,1,len[1][i]);
    105 }
    106 int read()
    107 {
    108     char s=getchar();
    109     int a=0,flag=1;
    110     while(s<'0'||s>'9')
    111     {
    112         if(s=='-')
    113             flag=-1;
    114         s=getchar();
    115     }
    116     while(s>='0'&&s<='9')
    117     {
    118         a=a*10+s-'0';
    119         s=getchar();
    120     }
    121     return flag*a;
    122 }
    123 int main()
    124 {
    125     n=read(),m=read();
    126     for(int i=1;i<=m;i++)
    127         len[read()][read()]=read();
    128     make();
    129     zkw();
    130     printf("%d %d",anst,ansl);
    131 }
    连续最短路

    hungary(hdu2063):

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<vector>
     4 #include<cstring>
     5 using namespace std;
     6 int n,linker[510],m,k;
     7 bool book[510];
     8 vector<int>f[510];
     9 bool dfs(int x)
    10 {
    11     for(int i=0;i<f[x].size();i++)
    12     {
    13         if(!book[f[x][i]])
    14         {
    15             book[f[x][i]]=true;
    16             if(linker[f[x][i]]==-1||dfs(linker[f[x][i]]))
    17             {
    18                 linker[f[x][i]]=x;
    19                 return true;    
    20             }    
    21         }    
    22     }
    23     return false;
    24 }
    25 int hungary()
    26 {
    27     int tot=0;
    28     memset(linker,-1,sizeof(linker));
    29     for(int i=1;i<=m;i++)
    30     {
    31         memset(book,false,sizeof(book));
    32         if(dfs(i))
    33             tot++;    
    34     }    
    35     return tot;
    36 }
    37 int main()
    38 {
    39     int a,b;
    40     while(~scanf("%d",&k)&&k!=0)
    41     {
    42         scanf("%d%d",&m,&n);
    43         for(int i=1;i<=501;i++)
    44             f[i].clear();
    45         for(int i=1;i<=k;i++)
    46         {
    47             scanf("%d%d",&a,&b);
    48             f[a].push_back(b);    
    49         }
    50         printf("%d
    ",hungary());
    51     }
    52 }
    hungary

    Hopcroft-Karp(cogs14):

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<queue>
      4 using namespace std;
      5 const int N=101;
      6 const int INF=1<<30;
      7 int g[N][N];
      8 int Mx[N];
      9 int My[N];
     10 int dx[N];
     11 int dy[N];
     12 bool used[N];
     13 int Nx,Ny,dis,n;
     14 bool searchP()
     15 {  
     16     dis=INF;
     17     int i,v,u;
     18     queue<int>Q;
     19     memset(dx,-1,sizeof(dx));
     20     memset(dy,-1,sizeof(dy));
     21     for(i=0;i<Nx;i++)
     22     {
     23         if(Mx[i]==-1)
     24         {
     25             Q.push(i);
     26             dx[i]=0;
     27         }
     28     }
     29     while(!Q.empty())
     30     {
     31         u=Q.front();
     32         Q.pop();
     33         if(dx[u]>dis)
     34             break;
     35         for(v=0;v<Ny;v++)  
     36         {
     37             if(g[u][v]&&dy[v]==-1)
     38             {
     39                 dy[v]=dx[u]+1;
     40                 if(My[v]==-1)
     41                     dis=dy[v];
     42                 else
     43                 {
     44                     dx[My[v]]=dy[v]+1;
     45                     Q.push(My[v]);
     46                 }
     47             }
     48         }
     49     }
     50     return dis!=INF;
     51 }
     52 bool DFS(int u)
     53 {
     54     int v;
     55     for(v=0;v<Ny;v++)
     56     {
     57         if(g[u][v]&&!used[v]&&dy[v]==dx[u]+1)
     58         {
     59             used[v]=true;
     60             if(My[v]!=-1&&dy[v]==dis)
     61                 continue;
     62             if(My[v]==-1||DFS(My[v]))
     63             {
     64                 My[v]=u;
     65                 Mx[u]=v;
     66                 return true;
     67             }
     68         }
     69     }
     70     return false;
     71 }
     72 int Hopcroft-Karp()
     73 {
     74     int u;
     75     int ret=0;
     76     memset(Mx,-1,sizeof(Mx));
     77     memset(My,-1,sizeof(My));
     78     while(searchP())
     79     {
     80         memset(used,false,sizeof(used));
     81         for(u=0;u<Nx;u++)
     82            if(Mx[u]==-1&&DFS(u))
     83                ret++;
     84     }
     85     return ret;
     86 }
     87 int main()
     88 {
     89     freopen("flyer.in","r",stdin);
     90     freopen("flyer.out","w",stdout);
     91     int k,u,v;
     92     scanf("%d%d",&n,&Nx);
     93     Ny=n-Nx;
     94     memset(g,0,sizeof(g));
     95     while(scanf("%d%d",&u,&v)!=EOF)
     96     {
     97         u--;
     98         v-=Nx+1;
     99         g[u][v]=1;
    100     }
    101     int ans=Hopcroft-Karp();
    102     printf("%d",ans);
    103 } 
    Hopcroft-Karp

    Kuhn-Munkras(hdu2255):

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int INF=0x3f3f3f3f;
     6 int n,f[310][310],linker[310];
     7 bool visx[310],visy[310];
     8 int lx[310],ly[310],slack[310];
     9 bool dfs(int x)
    10 {
    11     int t;
    12     visx[x]=true;
    13     for(int i=1;i<=n;i++)
    14     {
    15         if(visy[i])
    16             continue;
    17         t=lx[x]+ly[i]-f[x][i];
    18         if(t==0)
    19         {
    20             visy[i]=true;
    21             if(linker[i]==-1||dfs(linker[i]))
    22             {
    23                 linker[i]=x;
    24                 return true;    
    25             }    
    26         }    
    27         else if(slack[i]>t)
    28             slack[i]=t;
    29     }
    30     return false;
    31 }
    32 int km()
    33 {
    34     memset(linker,-1,sizeof(linker));
    35     memset(ly,0,sizeof(ly));
    36     for(int i=1;i<=n;i++)
    37     {
    38         lx[i]=-INF;
    39         for(int j=1;j<=n;j++)
    40             lx[i]=max(lx[i],f[i][j]);
    41     }
    42     for(int i=1;i<=n;i++)
    43     {
    44         for(int j=1;j<=n;j++)
    45             slack[j]=INF;
    46         while(1)
    47         {
    48             memset(visx,false,sizeof(visx));
    49             memset(visy,false,sizeof(visy));
    50             if(dfs(i))
    51                 break;
    52             int d=INF;
    53             for(int j=1;j<=n;j++)
    54                 if(!visy[j])
    55                     d=min(slack[j],d);
    56             for(int j=1;j<=n;j++)
    57                 if(visx[j])
    58                     lx[j]-=d;
    59             for(int j=1;j<=n;j++)
    60                 if(visy[j])
    61                     ly[j]+=d;
    62                 else
    63                     slack[j]-=d;
    64         }
    65     }
    66     int tot=0;
    67     for(int i=1;i<=n;i++)
    68         if(linker[i]!=-1)
    69             tot+=f[linker[i]][i];
    70     return tot;
    71 }
    72 int main()
    73 {
    74     while(~scanf("%d",&n))
    75     {
    76         for(int i=1;i<=n;i++)
    77             for(int j=1;j<=n;j++)
    78                 scanf("%d",&f[i][j]);
    79         printf("%d
    ",km());    
    80     }
    81     //while(1);
    82 }
    Kuhn-Munkras
  • 相关阅读:
    【CF1023D】Array Restoration(构造,线段树)
    【CF1020E】Sergey's problem(构造)
    【CF1020D】The hat(交互,二分)
    【CF1017F】The Neutral Zone(Bitset,埃氏筛)
    【CF1016F】Road Projects(贪心)
    【ZOJ4063】Tournament(构造)
    EQueue
    领域驱动设计(DDD)部分核心概念的个人理解
    DDD CQRS架构和传统架构的优缺点比较
    限流算法-三种思路
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7255481.html
Copyright © 2011-2022 走看看