网络流模板:最大流ISAP算法和Dinic算法

来源:互联网 发布:java 数组分割 编辑:程序博客网 时间:2024/06/11 18:39

ISAP:

 

#include<cstdio>#include<cstring>#include<queue>#include<algorithm>#define N 505#define inf 999999999using namespace std;int n,m,s,t,dis[N],pre[N],gap[N],flow[N][N];struct edge{int v,w;edge *next,*rev;edge(){next=0;}edge(int vv,int ww,edge *e){v=vv;w=ww;next=e;}}*adj[N],*path[N],*e;void insert(int u,int v,int w){edge *p=new edge(v,w,adj[u]);adj[u]=p;edge *q=new edge(u,0,adj[v]);adj[v]=q;p->rev=q;q->rev=p;}void bfs(){memset(dis,0x7f,sizeof(dis));memset(gap,0,sizeof(gap));queue<int> q;dis[t]=0;gap[0]=1;q.push(t);while(q.size()){int x=q.front();q.pop();for(e=adj[x];e;e=e->next){if(e->rev->w==0||dis[e->v]<t)continue;dis[e->v]=dis[x]+1;++gap[dis[e->v]];q.push(e->v);}}}int ISAP(){memset(dis,0,sizeof(dis));memset(gap,0,sizeof(gap));//bfs();int ans=0,u=s,d;while(dis[s]<=t){if(u==t){int minflow=-1u>>1;for(e=path[u];u!=s;e=path[u=pre[u]])minflow=min(minflow,e->w);for(e=path[u=t];u!=s;e=path[u=pre[u]]){e->w-=minflow;e->rev->w+=minflow;flow[pre[u]][u]+=minflow;flow[u][pre[u]]-=minflow;}ans+=minflow;}for(e=adj[u];e;e=e->next)if(e->w>0&&dis[u]==dis[e->v]+1)break;if(e){pre[e->v]=u;path[e->v]=e;u=e->v;}else{if(--gap[dis[u]]==0)break;for(d=t,e=adj[u];e;e=e->next)if(e->w>0)d=min(d,dis[e->v]);dis[u]=d+1;++gap[dis[u]];if(u!=s)u=pre[u];}}return ans;}int main(){int u,v,w;while(~scanf("%d%d",&m,&n)){memset(adj,0,sizeof(adj));while(m--){scanf("%d%d%d",&u,&v,&w);insert(u,v,w);//insert(v,u,w);//无向边}s=1;t=n;printf("%d\n",ISAP());}}/*6 53 4 54 5 51 2 102 3 101 3 202 5 20*/


 

Dinic:

 

#include<cstdio>#include<cstring>#include<algorithm>#define N 5005#define M 10005#define inf 999999999using namespace std;int n,m,s,t,num,adj[N],dis[N],q[N];struct edge{int v,w,pre;}e[M];void insert(int u,int v,int w){e[num]=(edge){v,w,adj[u]};adj[u]=num++;e[num]=(edge){u,0,adj[v]};adj[v]=num++;}int bfs(){int i,x,v,tail=0,head=0;memset(dis,0,sizeof(dis));dis[s]=1;q[tail++]=s;while(head<tail){x=q[head++];for(i=adj[x];i!=-1;i=e[i].pre)if(e[i].w&&dis[v=e[i].v]==0){dis[v]=dis[x]+1;if(v==t)return 1;q[tail++]=v;}}return 0;}int dfs(int s,int limit){if(s==t)return limit;int i,v,tmp,cost=0;for(i=adj[s];i!=-1;i=e[i].pre)if(e[i].w&&dis[s]==dis[v=e[i].v]-1){tmp=dfs(v,min(limit-cost,e[i].w));if(tmp>0){e[i].w-=tmp;e[i^1].w+=tmp;cost+=tmp;if(limit==cost)break;}else dis[v]=-1;}return cost;}int Dinic(){int ans=0;while(bfs())ans+=dfs(s,INT_MAX);return ans;}int main (){while(~scanf("%d%d",&m,&n)){int u,v,w;memset(adj,-1,sizeof(adj));num=0;s=1;t=n;while(m--){scanf("%d%d%d",&u,&v,&w);insert(u,v,w);}printf("%d\n",Dinic());}}