网络流+二分图模板
最大流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 }
连续最短路(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 }
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 }
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 }