最大流 总结

HDU3549  基础    难度1

HDU3046 狼羊模型 基础割 难度2

HDU1532 基础 难度1

HDU3605  可以状态压缩 难度2

HDU3572  卡时间,sap,dinic效率的比较 难度2 ----->HDU2883  一样以时间为点,但是这个时间跨度大,需要压缩 难度3.5

HDU3081   男女配对问题 难度3

HDU2732  拆点  难度3

HDU1879+3917 最大权闭合图 难度3.5

HDU3468 +最短路 难度3

HDU1569 1565方格取数 难度2.5

HDU3529
#include<cstdio> #include<cstdlib> #include<iostream> #include<memory.h> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int maxn=2010; const int inf=0x7fffffff; int vd[maxn],dis[maxn]; int Laxt[maxn],Next[maxn],To[maxn],V[maxn]; int n,m,cnt,ans; void _update() { memset(Laxt,0,sizeof(Laxt)); memset(vd,0,sizeof(vd)); memset(dis,0,sizeof(dis)); memset(V,0,sizeof(V)); cnt=2; ans=0; } void _add(int u,int v,int c) { Next[cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; V[cnt++]=c; Next[cnt]=Laxt[v]; Laxt[v]=cnt; To[cnt]=u; V[cnt++]=0; } int _sap(int u,int flow) { int tmp,delta=0; if(flow==0||u==n) return flow; for(int i=Laxt[u];i;i=Next[i]) { if(dis[To[i]]+1==dis[u]&&V[i]>0){ tmp=_sap(To[i],min(flow-delta,V[i])); V[i]-=tmp; V[i^1]+=tmp; delta+=tmp; if(delta==flow||dis[1]>=n) return delta; } } vd[dis[u]]--; if(vd[dis[u]]==0) dis[1]=n; vd[++dis[u]]++; return delta; } int main() { int T,t,i,j,x,y,z; cin>>T; for(t=1;t<=T;t++){ scanf("%d%d",&n,&m); _update(); for(i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&z); _add(x,y,z); } while(dis[1]<n){ ans+=_sap(1,inf); } printf("Case %d: %d ",t,ans); } return 0; }

 

HDU3046
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<memory.h>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxm=401000;
const int maxn=210;
const int inf=0x7fffffff;
int vd[maxn],dis[maxn];
int Laxt[maxn],Next[maxm],To[maxm],V[maxm];
int n,m,cnt,ans,s,t;
int num[220][220];
int x[4]={0,1,0,-1};
int y[4]={1,0,-1,0};
void _update()
{
    memset(Laxt,0,sizeof(Laxt));
    memset(vd,0,sizeof(vd));
    memset(dis,0,sizeof(dis));
    memset(V,0,sizeof(V));
    cnt=2;
    ans=0;
}
void _add(int u,int v,int c)
{
    Next[cnt]=Laxt[u];
    Laxt[u]=cnt;
    To[cnt]=v;
    V[cnt++]=c;
    Next[cnt]=Laxt[v];
    Laxt[v]=cnt;
    To[cnt]=u;
    V[cnt++]=0;
}
int _sap(int u,int flow)
{
    int tmp,delta=0;
    if(flow==0||u==t) return flow;
    for(int i=Laxt[u];i;i=Next[i])
    {
        if(dis[To[i]]+1==dis[u]&&V[i]>0){
            tmp=_sap(To[i],min(flow-delta,V[i]));
            V[i]-=tmp;
            V[i^1]+=tmp;
            delta+=tmp;
            if(delta==flow||dis[s]>t) return delta;
        }
    }
    vd[dis[u]]--;
    if(vd[dis[u]]==0) dis[s]=t+1;
    vd[++dis[u]]++;
    return delta;
}
int main()
{
    int n,m,i,j,Case=0;
    while(~scanf("%d%d",&n,&m))
    {
         s=0;t=n*m+1;
         _update();
         for(i=1;i<=n;i++)
          for(j=1;j<=m;j++)
            scanf("%d",&num[i][j]);
         for(i=1;i<=n;i++)
          for(j=1;j<=m;j++){    
                for(int k=0;k<4;k++)
                if(i+x[k]>=1&&j+y[k]>=1&&i+x[k]<=n&&j+y[k]<=m){
                    if(num[i][j]==0&&num[i+x[k]][j+y[k]]==0)
                      _add((i-1)*m+j,(i+x[k]-1)*m+j+y[k],1);
                    else if(num[i][j]!=num[i+x[k]][j+y[k]])
                      _add((i-1)*m+j,(i+x[k]-1)*m+j+y[k],1);
                }
                if(num[i][j]==1) _add(s,(i-1)*m+j,4);
                if(num[i][j]==2) _add((i-1)*m+j,t,4);
          }
         while(dis[s]<t+1){
                ans+=_sap(s,inf);
         }
         printf("Case %d:
%d
",++Case,ans);        
    }
    return 0;
}
HDU1532
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<memory.h>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=2010;
const int inf=0x7fffffff;
int vd[maxn],dis[maxn];
int Laxt[maxn],Next[maxn],To[maxn],V[maxn];
int n,m,cnt,ans;
void _update()
{
    memset(Laxt,0,sizeof(Laxt));
    memset(vd,0,sizeof(vd));
    memset(dis,0,sizeof(dis));
    memset(V,0,sizeof(V));
    cnt=2;
    ans=0;
}
void _add(int u,int v,int c)
{
    Next[cnt]=Laxt[u];
    Laxt[u]=cnt;
    To[cnt]=v;
    V[cnt++]=c;
    Next[cnt]=Laxt[v];
    Laxt[v]=cnt;
    To[cnt]=u;
    V[cnt++]=0;
}
int _sap(int u,int flow)
{
    int tmp,delta=0;
    if(flow==0||u==n) return flow;
    for(int i=Laxt[u];i;i=Next[i])
    {
        if(dis[To[i]]+1==dis[u]&&V[i]>0){
            tmp=_sap(To[i],min(flow-delta,V[i]));
            V[i]-=tmp;
            V[i^1]+=tmp;
            delta+=tmp;
            if(delta==flow||dis[1]>=n) return delta;
        }
    }
    vd[dis[u]]--;
    if(vd[dis[u]]==0) dis[1]=n;
    vd[++dis[u]]++;
    return delta;
}
int main()
{
     int T,t,i,j,x,y,z;
      while(~scanf("%d%d",&m,&n)){
         _update();
         for(i=1;i<=m;i++){
             scanf("%d%d%d",&x,&y,&z);
             _add(x,y,z);
         }
         while(dis[1]<n){
                ans+=_sap(1,inf);
         }
         printf("%d
",ans);        
     }
     return 0;
}
HDU3572
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<memory.h>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=510000;
const int inf=0x7fffffff;
int vd[maxn],dis[maxn];
int Laxt[maxn],Next[maxn],To[maxn],V[maxn];
int n,m,cnt,ans,s,t,num;
void _update()
{
    memset(Laxt,0,sizeof(Laxt));
    memset(vd,0,sizeof(vd));
    memset(dis,0,sizeof(dis));
    memset(V,0,sizeof(V));
    cnt=2;
    ans=0;
    num=0;
}
void _add(int u,int v,int c)
{
    Next[cnt]=Laxt[u];
    Laxt[u]=cnt;
    To[cnt]=v;
    V[cnt++]=c;
    Next[cnt]=Laxt[v];
    Laxt[v]=cnt;
    To[cnt]=u;
    V[cnt++]=0;
}
int _sap(int u,int flow)
{
    int tmp,delta=0;
    if(flow==0||u==t) return flow;
    for(int i=Laxt[u];i;i=Next[i])
    {
        if(dis[To[i]]+1==dis[u]&&V[i]>0){
            tmp=_sap(To[i],min(flow-delta,V[i]));
            V[i]-=tmp;
            V[i^1]+=tmp;
            delta+=tmp;
            if(delta==flow||dis[s]>t) return delta;
        }
    }
    vd[dis[u]]--;
    if(vd[dis[u]]==0) dis[s]=t+1;
    vd[++dis[u]]++;
    return delta;
}
int main()
{
      int T,i,j,x,y,z,Case=0;
      scanf("%d",&T);
      while(T--){
         scanf("%d%d",&n,&m);
         s=0;t=500+n+1;
         _update();
         for(i=1;i<=n;i++){
             scanf("%d%d%d",&z,&x,&y);
             num+=z;
             for(j=x;j<=y;j++)
               _add(j,500+i,1);
             _add(500+i,t,z);
         }
         for(i=1;i<=500;i++)
          _add(s,i,m);
         while(dis[s]<=t){
                ans+=_sap(s,inf);
         }
         if(ans==num) printf("Case %d: Yes
",++Case);
         else printf("Case %d: No
",++Case);    
         printf("
");    
      }
      return 0;
}
HDU1569
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<memory.h>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxm=1000000;
int num;
int n,m,s=0,t,cnt;
long long ans,sum;
int Laxt[maxm],Next[maxm],To[maxm],V[maxm];
int vd[maxm],dis[maxm];
void _add(int u,int v,int c)
{
    Next[cnt]=Laxt[u];
    Laxt[u]=cnt;
    To[cnt]=v;
    V[cnt++]=c;
    Next[cnt]=Laxt[v];
    Laxt[v]=cnt;
    To[cnt]=u;
    V[cnt++]=0;
}
int _sap(int u,int flow)
{
    int tmp,delta=0;
    if(flow==0||u==t) return flow;
    for(int i=Laxt[u];i;i=Next[i])
    {
        if(dis[To[i]]+1==dis[u]&&V[i]>0){
            tmp=_sap(To[i],min(flow-delta,V[i]));
            V[i]-=tmp;
            V[i^1]+=tmp;
            delta+=tmp;
            if(delta==flow||dis[s]>t) return delta;
        }
    }
    vd[dis[u]]--;
    if(vd[dis[u]]==0) dis[s]=t+1;
    vd[++dis[u]]++;
    return delta;
}
int main()
{
    int i,j;
    while(~scanf("%d%d",&n,&m)){
        cnt=2;
        memset(Laxt,0,sizeof(Laxt));
        memset(dis,0,sizeof(dis));
        memset(vd,0,sizeof(vd));
        ans=0;sum=0;
        t=n*m+1;
        for(i=1;i<=n;i++)
         for(j=1;j<=m;j++){ 
                scanf("%d",&num);
                sum+=num;
                int tmp=(i-1)*m+j;
                if((i+j)%2==1) {
                   _add(s,tmp,num);
                   if(i>1) _add(tmp,tmp-m,inf);
                   if(i<n) _add(tmp,tmp+m,inf);
                   if(j>1) _add(tmp,tmp-1,inf);
                   if(j<m) _add(tmp,tmp+1,inf);
                }
                else  _add(tmp,t,num);
         }
        while(dis[s]<=t){
               ans+=_sap(s,inf);
        }
        printf("%lld
",sum-ans);
    }
    return 0;
}
HDU3605
#include<cstdio> #include<cstdlib> HDU1605代码丑,时间上海可以优化,Max,t可缩小 #include<iostream> #include<memory.h> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int maxm=401000; const int inf=0x7fffffff; int vd[maxm],dis[maxm]; int Laxt[maxm],Next[maxm],To[maxm],V[maxm]; int n,m,cnt,ans,s,t; int a[maxm],c[maxm]; void _update() { memset(Laxt,0,sizeof(Laxt)); memset(dis,0,sizeof(dis)); memset(vd,0,sizeof(vd)); memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); cnt=2; ans=0; } void _add(int u,int v,int c) { Next[cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; V[cnt++]=c; Next[cnt]=Laxt[v]; Laxt[v]=cnt; To[cnt]=u; V[cnt++]=0; } int _sap(int u,int flow) { int tmp,delta=0; if(flow==0||u==t) return flow; for(int i=Laxt[u];i;i=Next[i]) { if(dis[To[i]]+1==dis[u]&&V[i]>0){ tmp=_sap(To[i],min(flow-delta,V[i])); V[i]-=tmp; V[i^1]+=tmp; delta+=tmp; if(delta==flow||dis[s]>t) return delta; } } vd[dis[u]]--; if(vd[dis[u]]==0) dis[s]=t+1; vd[++dis[u]]++; return delta; } int main() { int n,m,i,j,Max,x; while(~scanf("%d%d",&n,&m)) { _update(); Max=0; for(i=1;i<=n;i++){ int tmp=0; for(j=1;j<=m;j++) { scanf("%d",&x); tmp=tmp*2+x; } if(tmp>Max) Max=tmp; a[tmp]++; } s=0;t=Max+m+1; for(i=1;i<=m;i++) scanf("%d",&c[i]); for(i=1;i<=Max;i++){ if(a[i]>0) { _add(0,i,a[i]); int k=m,p=i; while(k&&p){ int tmp=p%2; p/=2; if(tmp>0) _add(i,Max+k,inf); k--; } } } for(i=1;i<=m;i++) _add(Max+i,t,c[i]); while(dis[s]<=t) { ans+=_sap(s,inf); } if(ans==n) printf("YES "); else printf("NO "); } return 0; }
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<memory.h>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxm=401000;
const int inf=0x7fffffff;
int vd[maxm],dis[maxm];
int Laxt[maxm],Next[maxm],To[maxm],V[maxm];
int n,m,cnt,ans,s,t;
int a[maxm],c[maxm];
void _update()
{
    memset(Laxt,0,sizeof(Laxt));
    memset(dis,0,sizeof(dis));
    memset(vd,0,sizeof(vd));
    memset(a,0,sizeof(a));
    memset(c,0,sizeof(c));
    cnt=2;
    ans=0;
}
void _add(int u,int v,int c)
{
    Next[cnt]=Laxt[u];
    Laxt[u]=cnt;
    To[cnt]=v;
    V[cnt++]=c;
    Next[cnt]=Laxt[v];
    Laxt[v]=cnt;
    To[cnt]=u;
    V[cnt++]=0;
}
int _sap(int u,int flow)
{
    int tmp,delta=0;
    if(flow==0||u==t) return flow;
    for(int i=Laxt[u];i;i=Next[i])
    {
        if(dis[To[i]]+1==dis[u]&&V[i]>0){
            tmp=_sap(To[i],min(flow-delta,V[i]));
            V[i]-=tmp;
            V[i^1]+=tmp;
            delta+=tmp;
            if(delta==flow||dis[s]>t) return delta;
        }
    }
    vd[dis[u]]--;
    if(vd[dis[u]]==0) dis[s]=t+1;
    vd[++dis[u]]++;
    return delta;
}
int main()
{
    int n,m,i,j,Max,x;
    while(~scanf("%d%d",&n,&m))
    {
         _update();
         Max=0;
         for(i=1;i<=n;i++){
            int tmp=0;
            for(j=1;j<=m;j++) {
               scanf("%d",&x);
               tmp=tmp*2+x;
            }
            if(tmp>Max) Max=tmp;
            a[tmp]++;
         }
         s=0;t=Max+m+1;
         for(i=1;i<=m;i++) scanf("%d",&c[i]);
         for(i=1;i<=Max;i++){
                if(a[i]>0) {
                    _add(0,i,a[i]);
                    int k=m,p=i;
                    while(k&&p){
                        int tmp=p%2;
                        p/=2;
                        if(tmp>0) _add(i,Max+k,inf);
                        k--;
                    }
                }
         }
         for(i=1;i<=m;i++) _add(Max+i,t,c[i]);
         while(dis[s]<=t) {
                ans+=_sap(s,inf);
         }
         if(ans==n) printf("YES
");
         else printf("NO
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hua-dong/p/7644202.html