您的位置:首页 > 其它

BZOJ 1877

2016-03-08 13:07 204 查看
这题是最小费用最大流。

拆一下点即可,每个点拆成出点和入点。然后跑一边最小费用最大流,分别输出最大流和最小费用即可。

代码如下,啊,好慢→→

/**************************************************************
Problem: 1877
User: fantasticwtl
Language: C++
Result: Accepted
Time:908 ms
Memory:1724 kb
****************************************************************/
#include <cstdio>
#include <memory.h>
using namespace std;
int ans,ss,n,m,x,y,z,w[405][405],d[10001],q[10001],pr[10001];
bool ff[405],f[405][405];
bool spfa ()
{
memset(ff,0,sizeof(ff));memset(pr,0,sizeof(pr));memset(d,60,sizeof(d));
ff[n+1]=1;q[1]=n+1;int h=0,t=1;d[n+1]=0;
while(h<t){
h++;
for(int i=1;i<=2*n;i++)
if(f[q[h]][i]&&d[i]>d[q[h]]+w[q[h]][i]){
d[i]=d[q[h]]+w[q[h]][i];
pr[i]=q[h];
if(!ff[i])q[++t]=i,ff[i]=1;
}
ff[q[h]]=0;
}
if(d
>1000000)return 0;
ans+=d
;
return 1;
}
int main ()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&z),f[n+x][y]=1,w[n+x][y]+=z,w[y][n+x]-=z;//输入部分
for(int i=1;i<=n;i++)f[i][i+n]=1;//出点与入点连边
while(spfa ()){//最小费用最大流
int k=n;ss++;
while(k!=n+1)f[pr[k]][k]=0,f[k][pr[k]]=1,k=pr[k];
}
printf("%d %d\n",ss,ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: