bzoj1834(网络流加费用流)
2016-03-08 18:53
381 查看
1834: [ZJOI2010]network 网络扩容
Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 2390 Solved: 1206
[Submit][Status][Discuss]
Description
给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求: 1、 在不扩容的情况下,1到N的最大流; 2、 将1到N的最大流增加K所需的最小扩容费用。Input
输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。Output
输出文件一行包含两个整数,分别表示问题1和问题2的答案。Sample Input
5 8 21 2 5 8
2 5 9 9
5 1 6 2
5 1 1 8
1 2 8 7
2 5 4 9
1 2 1 1
1 4 2 1
Sample Output
13 1930%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10
解题思路:第一问就是最大流,然后第二问,可以对在建m条边,只是产生费用,再来一个源点,到一的容量为K。跑一边费用流。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,k,len,ans;
int from[21000],to[21000],cc[21000],ww[21000],next[21000];
int h[1100];
int dis[1100];
int q[1000000];
bool og[1100];
int pre[1100];
int x[5100],y[5100],c[5100],w[5100];
inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<'0' || y>'9') {if (y=='-') f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}
return x*f;
}
void insert(int x,int y,int c,int w)
{
++len;
from[len]=x; to[len]=y; cc[len]=c; ww[len]=w; next[len]=h[x]; h[x]=len;
}
int dicnic(int sum,int now)
{
if (now==n) return sum;
int u=h[now]; int sug=0;
while (u!=0)
{
if (cc[u]>0 && dis[now]+1==dis[to[u]])
{
int s=dicnic(min(cc[u],sum-sug),to[u]);
if (s>0)
{
sug+=s;
cc[u]-=s; cc[u^1]+=s;
if (sug==sum) return sum;
}
}
u=next[u];
}
if (sug==0) dis[now]=-1;
return sug;
}
bool bfs()
{
memset(dis,-1,sizeof(dis));
dis[1]=1; int tail=0,head=0; ++tail; q[tail]=1;
while (head<tail)
{
++head;
int u=h[q[head]];
while (u!=0)
{
if (cc[u]>0 && dis[to[u]]==-1)
{
dis[to[u]]=dis[q[head]]+1;
++tail; q[tail]=to[u];
}
u=next[u];
}
}
if (dis
!=-1) return true; else return false;
}
bool spfa()
{
memset(dis,0x7e,sizeof(dis));
memset(og,true,sizeof(og));
og[0]=false;
dis[0]=0; int tail=1,head=0; q[tail]=0;
while (head<tail)
{
++head;
int u=h[q[head]];
while (u!=0)
{
if (cc[u]>0 && dis[to[u]]>dis[q[head]]+ww[u])
{
pre[to[u]]=u;
dis[to[u]]=dis[q[head]]+ww[u];
if (og[to[u]])
{
og[to[u]]=false;
++tail; q[tail]=to[u];
}
}
u=next[u];
}
og[q[head]]=true;
}
if (dis
<1000000) return true;else return false;
}
void mcf()
{
int now=n; int zan=0x7fffffff;
while (now!=0)
{
zan=min(zan,cc[pre[now]]);
now=from[pre[now]];
}
now=n;
while (now!=0)
{
cc[pre[now]]-=zan; cc[pre[now]^1]+=zan;
ans+=zan*ww[pre[now]];
now=from[pre[now]];
}
}
int main()
{
n=read(); m=read(); k=read();
len=1;
for (int i=1;i<=m;++i)
{
x[i]=read(); y[i]=read(); c[i]=read(); w[i]=read();
insert(x[i],y[i],c[i],0); insert(y[i],x[i],0,0);
}
int sum=0;
while (bfs())
{
sum+=dicnic(0x7fffffff,1);
}
printf("%d ",sum);
insert(0,1,k,0); insert(1,0,-k,0);
for (int i=1;i<=m;++i)
{
insert(x[i],y[i],k,w[i]); insert(y[i],x[i],0,-w[i]);
}
ans=0;
while (spfa())
{
mcf();
}
printf("%d",ans);
}
相关文章推荐
- python 网络编程基础(一)
- Netty5.x如何用TCP/IP发送大文件到服务器
- ubuntu 14.04 安装phpMyAdmin + lighttpd
- 网络爬虫的基本原理(一)
- github上面的demo(包含了状态栏沉浸式,进度动画大全,自定义封装好的webView,recycleview的+swiprefreshLayout,tablayout,okhttp)
- AFHTTPRequestOperation做文件下载的断点续传
- Java网络编程(一)流
- 某某农业有限公司网络营销工作计划
- TCP性能优化
- TCP通信 ,Socket原理 ,服务端ServerSocket,客户端Socket
- Android网络通信之Socket
- 玩转OpenStack网络Neutron(2)--使用Open vSwitch实现VLAN类型租户网络
- 基于java的https双向认证,android上亦可用
- Tomcat配置https及访问http自动跳转至https
- Mybatis-Generator 详解 http://www.cnblogs.com/jtzfeng/p/5254798.html
- 对网络日志分析的几个方面
- Socket-TCP/UDP浅析
- mysql表数据发生变化时,主动通知业务系统(mysql-udf-http)
- Http协议
- php读取网络文件 curl, fsockopen ,file_get_contents 几个方法的效率对比