网络流
1.hdu3377:求最大流模板
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define REP(i,s,t) for(int i=s;i<=t;i++) #define qwq(x) for(edge *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar();bool f=true; while(!isdigit(c)) { if(c=='-') f=false;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return f?x:-x; } const int nmax=105; const int inf=0x7f7f7f7f; struct edge{ int to,cap;edge *next,*rev; }; edge edges[10005],*head[nmax],*pt; void add(int u,int v,int d){ pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++; } void adde(int u,int v,int d){ add(u,v,d);add(v,u,0);head[u]->rev=head[v];head[v]->rev=head[u]; } int cnt[nmax],h[nmax]; edge *p[nmax],*cur[nmax]; int maxflow(int s,int t,int n){ clr(cnt,0);cnt[0]=n;clr(h,0); int flow=0,a=inf,x=s;edge *e; while(h[s]<n){ for(e=cur[x];e;e=e->next) if(e->cap>0&&h[e->to]+1==h[x]) break; if(e){ p[e->to]=cur[x]=e;a=min(a,e->cap);x=e->to; if(x==t){ while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to; flow+=a;a=inf; } // flow+=a;a=inf; }else{ if(!--cnt[h[x]]) break; h[x]=n; for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e; cnt[h[x]]++; if(x!=s) x=p[x]->rev->to; } } return flow; } int main(){ int t=read(),n,m,u,v,d; rep(i,t){ clr(head,0);pt=edges; n=read(),m=read(); rep(j,m) u=read(),v=read(),d=read(),adde(u,v,d); /*rep(j,n){ qwq(j) printf("%d %d ",o->to,o->cap); printf("\n"); }*/ printf("Case %d: %d\n",i,maxflow(1,n,n)); } return 0; }
poj1273:。。。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar();bool f=true; while(!isdigit(c)) { if(c=='-') f=false;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } const int nmax=205; const int inf=0x7f7f7f7f; struct edge{ int to,cap;edge *next,*rev; }; edge edges[405],*pt,*head[nmax],*cur[nmax],*p[nmax]; int cnt[nmax],h[nmax]; void add(int u,int v,int d){ pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++; } void adde(int u,int v,int d){ add(u,v,d);add(v,u,0);head[u]->rev=head[v];head[v]->rev=head[u]; } int maxflow(int s,int t,int n){ clr(cnt,0);cnt[0]=n;clr(h,0); int flow=0,a=inf,x=s;edge *e; while(h[s]<n){ for(e=cur[x];e;e=e->next) if(e->cap>0&&h[e->to]+1==h[x]) break; if(e){ a=min(a,e->cap);p[e->to]=cur[x]=e;x=e->to; if(x==t){ while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to; flow+=a;a=inf; } }else{ if(!--cnt[h[x]]) break; h[x]=n; for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e; cnt[h[x]]++; if(x!=s) x=p[x]->rev->to; } } return flow; } int main(){ int n,m,u,v,d; while(scanf("%d%d",&m,&n)==2){ clr(head,0);pt=edges; rep(i,m) u=read(),v=read(),d=read(),adde(u,v,d); printf("%d\n",maxflow(1,n,n)); } return 0; }
poj3281:建图即可。s->F->k->k'->D->t;
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) int read(){ int x=0;char c=getchar();bool f=true; while(!isdigit(c)) { if(c=='-') f=false;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return f?x:-x; } const int nmax=405; const int maxn=50000; const int inf=0x7f7f7f7f; struct edge{ int to,cap;edge *next,*rev; }; edge edges[maxn],*pt,*head[nmax],*cur[nmax],*p[nmax]; int cnt[nmax],h[nmax]; void add(int u,int v,int d){ pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++; } void adde(int u,int v,int d){ add(u,v,d);add(v,u,0);head[u]->rev=head[v];head[v]->rev=head[u]; } int maxflow(int s,int t,int n){ clr(cnt,0);cnt[0]=n;clr(h,0); int flow=0,a=inf,x=s;edge *e; while(h[s]<n){ for(e=cur[x];e;e=e->next) if(e->cap>0&&h[e->to]+1==h[x]) break; if(e){ a=min(a,e->cap);p[e->to]=cur[x]=e;x=e->to; if(x==t){ while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to; flow+=a;a=inf; } }else{ if(!--cnt[h[x]]) break; h[x]=n; for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e; cnt[h[x]]++; if(x!=s) x=p[x]->rev->to; } } return flow; } int main(){ pt=edges; clr(head,0); int n=read(),F=read(),D=read(),tf,td,s=0,t=2*n+F+D+1,tmp; rep(i,n){ tf=read(),td=read(); rep(j,tf) tmp=read(),adde(tmp,F+i,1);; rep(j,td) tmp=read(),adde(F+n+i,F+n+n+tmp,1); adde(F+i, F+n+i,1); } rep(i,F) adde(s,i,1); rep(i,D) adde(F+n+n+i,t,1); printf("%d\n",maxflow(s,t,t+1)); return 0; }
2.最优匹配可以用最小费用最大流做。。。最大匹配可以用最大流做。。。不知道时间复杂度比较如何。。。应该是匈牙利比较快吧。。。
3.