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

【codevs1993】草地排水,网络流入门(dinic+ispa)

2016-02-17 10:43 627 查看
传送门

思路:裸

代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,tot=-1,x,y,z,s=1,t,ans;
int first[2000],dist[2000],up[2000];
struct os
{
int fa,son,remain,next;
}a[2000];
void add(int x,int y,int z)
{
a[++tot].fa=x;
a[tot].son=y;
a[tot].remain=z;
a[tot].next=first[x];
first[x]=tot;
}
void bfs()
{
memset(dist,0,sizeof(dist));
dist[s]=1;
queue<int> q;
q.push(s);
while (!q.empty())
{
int k=q.front();
q.pop();
for (int i=first[k];i!=-1;i=a[i].next)
if (!dist[a[i].son]&&a[i].remain)
q.push(a[i].son),
dist[a[i].son]=dist[k]+1;
}
}
int dfs(int now,int minn)
{
if (!minn||now==t) return minn;
int k,flow=0;
for (int i=up[now];i!=-1;i=a[i].next)
{
up[now]=i;
if (dist[now]+1==dist[a[i].son])
{
k=dfs(a[i].son,min(minn,a[i].remain));
a[i].remain-=k;
a[i xor 1].remain+=k;
flow+=k;
minn-=k;
if (!minn) break;
}
}
return flow;
}
main()
{
scanf("%d%d",&m,&n);
memset(first,-1,sizeof(first));
for (int i=1;i<=m;i++)
scanf("%d%d%d",&x,&y,&z),
add(x,y,z),
add(y,x,0);
t=n;
while (1)
{
bfs();
if (!dist[t]) break;
for (int i=1;i<=n;i++) up[i]=first[i];
ans+=dfs(s,0X7f);
}
printf("%d",ans);
}


ISPA(递归):

#include<bits/stdc++.h>
using namespace std;
int n,m,tot,ans;
int first[20000],dis[20000],last[20000],num[20000],up[20000];
struct os
{
int fa,son,remain,next;
}a[40000];
void add(int x,int y,int z)
{
a[++tot].fa=x;
a[tot].son=y;
a[tot].remain=z;
a[tot].next=first[x];
first[x]=tot;
}
inline int pd(int x)
{
if (x&1) return x+1;
return x-1;
}
int flow()
{
int limit=0x7fffffff;
for (int i=n;i!=1;i=a[pd(up[i])].son)
limit=min(limit,a[up[i]].remain);
for (int i=n;i!=1;i=a[pd(up[i])].son)
a[up[i]].remain-=limit,
a[pd(up[i])].remain+=limit;
return limit;
}
void bfs()
{
queue<int> q;
q.push(n);
dis
=1;
while (!q.empty())
{
int k=q.front();
q.pop();
for (int i=first[k];i;i=a[i].next)
if (!dis[a[i].son])
dis[a[i].son]=dis[k]+1,
q.push(a[i].son);
}
}
void search(int now,bool flag)
{
if (now==n)
{ans+=flow();flag=1;return;}
bool pd=0;
for (int i=first[now];i;i=a[i].next)
{
if (a[i].remain&&dis[a[i].son]+1==dis[now]) up[a[i].son]=last[now]=i,pd=1,search(a[i].son,flag);
if (flag) return;
}
if (!pd)
{
int minn=0x7fff;
for (int i=first[now];i;i=a[i].next)
if (a[i].remain)minn=min(minn,dis[a[i].son]);
if (--num[dis[now]]==0)
{printf("%d",ans);exit(0);}
dis[now]=minn+1;
last[now]=first[now];
num[dis[now]]++;
}
}
main()
{
scanf("%d%d",&m,&n);
int x,y,z;
for (int i=1;i<=m;i++)
scanf("%d%d%d",&x,&y,&z),
add(x,y,z),
add(y,x,0);
bfs();

for (int i=1;i<=n;i++) last[i]=first[i],num[dis[i]]++;
while (1)search(1,0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: