【链接】
poj1459
【题目大意】
给你4个数n,np,nc,m,接下来m条电力输送线(路径),np个电站(起点)和nc个消费者(终点),以及起点,终点和路径的限定的流量,求最大流。
【解题报告】
最大流模板题。
EK:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=105,maxm=20505,INF=((1<<30)-1)*2+1;
int n,nc,np,m,tot,st,gl,ans,son[maxm],w[maxm],nxt[maxm],lnk[maxn],que[maxn],f[maxn],fa[maxn],fa_e[maxn];
bool vis[maxn];
inline int read_()
{
int sum=0;
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') sum=sum*10+ch-48,ch=getchar();
return sum;
}
void add_(int x,int y,int z)
{
w[++tot]=z; son[tot]=y; nxt[tot]=lnk[x]; lnk[x]=tot;
}
int bfs_()
{
memset(vis,0,sizeof(vis));
memset(fa,0,sizeof(fa));
que[1]=st; vis[st]=true; f[st]=INF;
int hed=0,til=1;
while (hed!=til)
{
int x=que[++hed];
for (int j=lnk[x]; j; j=nxt[j])
if (!vis[son[j]]&&w[j]>0)
{
vis[son[j]]=true; que[++til]=son[j];
f[son[j]]=min(f[x],w[j]);
fa[son[j]]=x; fa_e[son[j]]=j;
if (son[j]==gl) return f[son[j]];
}
}
return 0;
}
void change_(int x)
{
int now=gl;
while (now!=st)
{
int j=fa_e[now];
w[j]-=x; w[j^1]+=x;
now=fa[now];
}
}
void work_()
{
st=n; gl=n+1;
memset(lnk,0,sizeof(lnk)); tot=1;
for (int i=1; i<=m; i++)
{
int x=read_(),y=read_(),z=read_();
add_(x,y,z); add_(y,x,0);
}
for (int i=1; i<=np; i++)
{
int x=read_(),z=read_();
add_(st,x,z); add_(x,st,0);
}
for (int i=1; i<=nc; i++)
{
int x=read_(),z=read_();
add_(x,gl,z); add_(gl,x,0);
}
ans=0;
while (1)
{
int x=bfs_();
if (x==0) break;
change_(x); ans+=x;
}
printf("%d\n",ans);
}
int main()
{
freopen("1459.in","r",stdin);
freopen("1459.out","w",stdout);
while (scanf("%d%d%d%d",&n,&np,&nc,&m)==4) work_();
return 0;
}
Dinic:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=105,maxm=200005,INF=((1<<30)-1)*2+1;
int n,m,tot,np,nc,st,gl,dst[maxn],w[maxm],son[maxm],nxt[maxm],lnk[maxn],que[maxn],cur[maxn];
bool vis[maxn];
inline int Read()
{
int res=0;
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') res=res*10+ch-48,ch=getchar();
return res;
}
void Add(int x,int y,int z)
{
w[tot]=z; son[tot]=y; nxt[tot]=lnk[x]; lnk[x]=tot; tot++;
w[tot]=0; son[tot]=x; nxt[tot]=lnk[y]; lnk[y]=tot; tot++;
}
bool Bfs(int s,int t)
{
memset(vis,0,sizeof(vis));
memset(dst,0,sizeof(dst));
int hed=0,til=1; que[1]=s; vis[s]=1; dst[s]=0;
while (hed!=til)
{
int x=que[++hed];
for (int j=lnk[x]; ~j; j=nxt[j])
if (!vis[son[j]]&&w[j]) vis[son[j]]=1,dst[son[j]]=dst[x]+1,que[++til]=son[j];
}
return vis[t];
}
int Dfs(int x,int t,int MIN)
{
if (x==t||MIN==0) return MIN;
int Flow=0;
for (int &j=cur[x]; ~j; j=nxt[j])
if (dst[x]+1==dst[son[j]])
{
int now=Dfs(son[j],t,min(MIN,w[j]));
if (now)
{
w[j]-=now; w[j^1]+=now; Flow+=now; MIN-=now;
if (!MIN) break;
}
}
return Flow;
}
int MAXFlow(int s,int t)
{
int Flow=0;
while (Bfs(s,t))
{
memcpy(cur,lnk,sizeof(cur));
Flow+=Dfs(s,t,INF);
}
return Flow;
}
void Work()
{
st=n; gl=n+1; tot=0;
memset(lnk,255,sizeof(lnk));
for (int i=1,x,y,z; i<=m; i++) x=Read(),y=Read(),z=Read(),Add(x,y,z);
for (int i=1,y,z; i<=np; i++) y=Read(),z=Read(),Add(st,y,z);
for (int i=1,x,z; i<=nc; i++) x=Read(),z=Read(),Add(x,gl,z);
printf("%d\n",MAXFlow(st,gl));
}
int main()
{
freopen("1459.in","r",stdin);
freopen("1459.out","w",stdout);
while (scanf("%d%d%d%d",&n,&np,&nc,&m)==4) Work();
return 0;
}