您的位置:首页 > 理论基础 > 计算机网络

hdu3549 Flow Problem 网络最大流的三种写法(Ek,Dinic(邻接矩阵,邻接表),Isap)

2016-11-02 12:43 537 查看
初学网络流,自己理解了网络流的三种求法,在这里贴下自己写的模板

hdu3549 Flow Problem

#include<stdio.h>  //EK模板
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 20
#define inf 0x3f3f3f3f
int cap[maxn][maxn],flow[maxn][maxn],pre[maxn],a[maxn],n,m;
int e_k()
{
queue<int>q;
memset(flow,0,sizeof(flow));
int i,u,ans=0;
for(;;)
{
q.push(1);
memset(a,0,sizeof(a));
a[1]=inf;
while(!q.empty())
{
u=q.front();
q.pop();
for(i=1; i<=n; i++)
if(!a[i]&&cap[u][i]>flow[u][i])
a[i]=min(a[u],cap[u][i]-flow[u][i]),q.push(i),pre[i]=u;
}
if(!a
) break;
for(i=n;i!=1;i=pre[i])
flow[pre[i]][i]+=a
,flow[i][pre[i]]-=a
;
ans+=a
;
}
return ans;
}
int main()
{
int nn,ss=0;
scanf("%d",&nn);
while(nn--)
{
memset(cap,0,sizeof(cap));
int x,y,z,i;
scanf("%d%d",&n,&m);
for(i=1; i<=m; i++)
scanf("%d%d%d",&x,&y,&z),cap[x][y]+=z;
printf("Case %d: %d\n",++ss,e_k());
}
}


#include<stdio.h>//Dinic模板
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define spot 200+10
#define edge 1000+10
#define inf 0x3f3f3f3f
struct stu
{
int to,cap,next;
} a[edge<<1];
int head[spot],n,m,s,t,sizes,dis[spot];
void init()
{
sizes=0;
memset(head,-1,sizeof(head));
}
void add_edge(int from,int to,int cap)
{
a[sizes].to=to,a[sizes].cap=cap;
a[sizes].next=head[from];
head[from]=sizes++;
}
bool bfs(int s,int t)
{
queue<int>q;
memset(dis,0,sizeof(dis));
dis[s]=1;
q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=head[now]; i+1; i=a[i].next)
{
int v=a[i].to;
if(!dis[v]&&a[i].cap)
{
dis[v]=dis[now]+1;
if(v==t) return 1;
q.push(v);
}
}
}
return dis[t];
}
int dfs(int s,int t,int cp)
{
if(s==t||!cp) return cp;
int r=0;
for(int i=head[s]; i+1; i=a[i].next)
{
int to=a[i].to;
if(a[i].cap&&dis[to]==dis[s]+1)
{
int d=dfs(to,t,min(cp,a[i].cap));
if(d>0)
{
a[i].cap-=d;
a[i^1].cap+=d;
r+=d;
cp-=d;
if(!cp) break;
}
}
}
if(!r) dis[s]=inf;
return r;
}
int dinic(int s,int t)
{
int r=0;
while(bfs(s,t))   r+=dfs(s,t,inf);
return r;
}
int main()
{
int nn,ss=0;
scanf("%d",&nn);
while(nn--)
{
scanf("%d%d",&n,&m);
int i,x,y,z;
init();
for(i=1; i<=m; i++)
scanf("%d%d%d",&x,&y,&z),add_edge(x,y,z),add_edge(y,x,0);
printf("Case %d: %d\n",++ss,dinic(1,n));
}
return 0;
}


#include<bits/stdc++.h>  //Isap邻接表模板
using namespace std;
#define spot 200+10
#define edge 200+10
#define inf 0x3f3f3f3f
struct stu
{
int to,flow,cap,next;
} a[edge];
int sizes,gap[edge],head[edge],cur[edge],dis[edge],pre[spot];
void init()
{
sizes=0;
memset(head,-1,sizeof(head));
}
void add_edge(int from,int to,int cap)
{
a[sizes].to=to;
a[sizes].cap=cap;
a[sizes].flow=0;
a[sizes].next=head[from];
head[from]=sizes++;
}
void bfs(int start,int over)
{
queue<int>q;
q.push(over);
memset(dis,0,sizeof(dis));
memset(gap,0,sizeof(gap));
dis[over]=1;
int k,u,v;
while(!q.empty())
{
u=q.front();
q.pop();
for(k=head[u]; k+1; k=a[k].next)
{
v=a[k].to;
if(!dis[v])
{
dis[v]=dis[u]+1;
q.push(v);
gap[dis[v]]++;
}
}
}
}
int isap(int start,int over,int n)
{
bfs(start,over);
memcpy(cur,head,sizeof(cur));
int top=0,u=start,ans=0,i,v,k;
while(dis[start]<=n)
{
if(u==over)
{
int Min=inf;
int temp;
for(i=0; i<top; i++)
if(Min>a[pre[i]].cap-a[pre[i]].flow)
Min=a[pre[i]].cap-a[pre[i]].flow,temp=i;
for(i=0; i<top; i++)
a[pre[i]].flow+=Min,a[pre[i]^1].flow-=Min;
ans+=Min;
top=temp;
u=a[pre[top]^1].to;
continue;
}
bool flag=0;
for(k=cur[u]; k+1; k=a[k].next)
{
v=a[k].to;
if(a[k].cap>a[k].flow&&dis[v]+1==dis[u])
{
flag=1;
cur[u]=k;
break;
}
}
if(flag)
{
pre[top++]=cur[u];
u=v;
continue;
}
int minn=n;
for(k=head[u]; k+1; k=a[k].next)
{
if(a[k].cap>a[k].flow&&dis[a[k].to]<minn)
minn=dis[a[k].to],cur[u]=k;
}
gap[dis[u]]--;
if(!gap[dis[u]])  return ans;
dis[u]=minn+1;
gap[dis[u]]++;
if(u!=start)
u=a[pre[--top]^1].to;
}
return ans;
}
int main()
{
int n,m;
while(scanf("%d%d",&m,&n)!=EOF)
{
int i,x,y,z,s,t;
init();
for(i=1; i<=m; i++)
scanf("%d%d%d",&x,&y,&z),add_edge(x,y,z),add_edge(y,x,0);
s=1,t=n;
printf("%d\n",isap(s,t,n));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: