网络流+二分图模板

最大流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\n",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\n",km());    
80     }
81     //while(1);
82 }
Kuhn-Munkras

 

posted @ 2017-07-29 12:06  avancent  阅读(155)  评论(0编辑  收藏  举报