一道不算太难的题目

但是真的很恶心

显然,对于第一问,我们直接无脑打模板就好了

第二问也不是很难,我们将每条边再连一条容量为inf,费用为w的边

但是流量只要小于第一问的答案加k就行了

所以我们增加一个点为第二问的汇点,将n与它连接一条容量为ans+k,费用为0的边

跑费用流就好了

但是!!!!!!!

这样作只有40分,为什么呢。

因为虽然数据范围说n<=1000但给的点编号有大于1000的点。。。。。

我们只要将点数视为5000就可以过来了

真的恶心。。。。

不过在考场上还是建议用离散化,毕竟你不知道点数编号的范围

想问一问当初省选时有多少人被这个给坑了。。

# include<iostream>
# include<cstdio>
# include<cmath>
# include<algorithm>
# include<cstring>
# include<queue>
using namespace std;
const int mn = ;
const int inf = 0xfffffff;
struct edge{
int to,next,flow,cup,cost;
edge(){to=flow=cup=cost=,next=-;}
};
edge e[mn*];
int head[mn],edge_max=-;
void add(int x,int y,int k,double c)
{
e[++edge_max].to=y;
e[edge_max].next=head[x];
e[edge_max].flow=e[edge_max].cup=k;
e[edge_max].cost=c;
head[x]=edge_max;
}
int n,m,k;
int ans1,ans2;
int deep[mn];
int cur[mn];
queue<int> q;
bool bfs(int x,int y)
{
memset(deep,,sizeof(deep));
q.push(x);
deep[x]=;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i!=-;i=e[i].next)
{
if(deep[e[i].to]== && e[i].flow> )
{
deep[e[i].to]=deep[u]+;
q.push(e[i].to);
}
}
}
if(deep[y]==)
return false;
else return true;
}
int dfs(int x,int dist,int y)
{
if(x==y)
return dist;
for(int &i=cur[x];i!=-;i=e[i].next)
{
if(deep[e[i].to]==deep[x]+ && e[i].flow!=)
{
int di=dfs(e[i].to,min(dist,e[i].flow),y);
if(di>)
{
e[i].flow-=di;
e[i^].flow+=di;
return di;
}
}
}
return ;
}
void dinic(int x,int y)
{
while(bfs(x,y))
{
for(int i=;i<=n;i++)
cur[i]=head[i];
while(int k=dfs(x,inf,y))
ans1+=k;
}
}
int dis[mn];
int pe[mn],pv[mn];
bool vis[mn];
bool spfa(int x,int y)
{
memset(vis,,sizeof(vis));
for(int i=;i<=n+;i++)
dis[i]=inf;
dis[x]=;
vis[x]=;
q.push(x);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=;
for(int i=head[u];i!=-;i=e[i].next)
{
if(dis[u]+e[i].cost<dis[e[i].to] && e[i].flow>)
{
dis[e[i].to]=e[i].cost+dis[u];
pe[e[i].to]=i;
pv[e[i].to]=u;
if(!vis[e[i].to])
{
q.push(e[i].to);
vis[e[i].to]=;
}
}
}
}
if(dis[y]!=inf)
return true;
else return false;
}
void max_flow(int x,int y)
{
while(spfa(x,y))
{
int mflow=inf;
for(int i=y;i!=x;i=pv[i])
{
mflow=min(mflow,e[pe[i]].flow);
}
ans2+=dis[y]*mflow;
for(int i=y;i!=x;i=pv[i])
{
e[pe[i]].flow-=mflow;
e[pe[i]^].flow+=mflow;
}
}
}
int a1[mn],a2[mn],a3[mn],a4[mn];
void pre()
{
memset(head,-,sizeof(head));
memset(e,-,sizeof(e));
for(int i=;i<=m;i++)
{
add(a1[i],a2[i],a3[i],);
add(a2[i],a1[i],,);
add(a1[i],a2[i],inf,a4[i]);
add(a2[i],a1[i],,-a4[i]);
}
}
int main()
{
int x,y,c,w;
memset(head,-,sizeof(head));
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=m;i++)
{
scanf("%d%d%d%d",&a1[i],&a2[i],&a3[i],&a4[i]);
add(a1[i],a2[i],a3[i],);
add(a2[i],a1[i],,);
}
dinic(,n);
pre();
add(n,n+,ans1+k,);
add(n+,n,,);
max_flow(,n+);
printf("%d %d",ans1,ans2);
return ;
}

BZOJ 1834网络扩容题解的更多相关文章

  1. BZOJ 1834 网络扩容 最大流+最小费用流

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1834 题目大意: 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是 ...

  2. BZOJ 1834 网络扩容(最大流+费用流)

    对于第一问,直接求最大流. 对于第二问,建源点s和汇点t,s连1容量为INF,费用为0的边,n连t容量为最大流+k,费用为0的边.这样就把最大流限制为最多增加k了. 限制需要求扩充的最小费用,原图的边 ...

  3. BZOJ1834:[ZJOI2010]网络扩容——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1834 https://www.luogu.org/problemnew/show/P2604#sub ...

  4. 【BZOJ】【1834】【ZJOI2010】Network 网络扩容

    网络流/费用流 这题……我一开始sb了. 第一问简单的最大流…… 第二问是要建费用流的图的……但是是在第一问的最大流跑完以后的残量网络上建,而不是重建…… 我们令残量网络上原有的弧的费用全部为0(因为 ...

  5. BZOJ 1834: [ZJOI2010]network 网络扩容(最大流+最小费用最大流)

    第一问直接跑最大流.然后将所有边再加一次,费用为扩容费用,容量为k,再从一个超级源点连一条容量为k,费用为0的边到原源点,从原汇点连一条同样的边到超级汇点,然  后跑最小费用最大流就OK了. ---- ...

  6. bzoj 1834: [ZJOI2010]network 网络扩容 -- 最大流+费用流

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Description 给定一张有向图,每条边都有一个容量C和一 ...

  7. 【题解】Luogu P2604 [ZJOI2010]网络扩容

    原题传送门:P2604 [ZJOI2010]网络扩容 这题可以说是板题 给你一个图,先让你求最大流 再告诉你,每条边可以花费一些代价,使得流量加一 问至少花费多少代价才能使最大流达到k 解法十分简单 ...

  8. 【bzoj1834】[ZJOI2010]network 网络扩容

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 2701  Solved: 1368[Submit ...

  9. C++之路进阶——codevs1362(网络扩容)

    1362 网络扩容 省队选拔赛  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 大师 Master     题目描述 Description 给定一张有向图,每条边都有一个容量 ...

随机推荐

  1. LINUX超级用户(权限)在系统管理中的作用

    1.对任何文件.目录或进程进行操作: 但值得注意的是这种操作是在系统最高许可范围内的操作:有些操作就是具有超级权限的root也无法完成: 比如/proc 目录,/proc 是用来反应系统运行的实时状态 ...

  2. Leetcode441Arranging Coins排列硬币

    你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币. 给定一个数字 n,找出可形成完整阶梯行的总行数. n 是一个非负整数,并且在32位有符号整型的范围内. 示例 ...

  3. spotbus gradle-qulity-plugiin 多项目bug检查

    https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html https://xvik.github.io/gradle-quality ...

  4. poj1961

    poj1961主要是考察对next数组的理解,abaabaabaaba abaabaabaabaabaaba错开的部分便是循环节 7月29日更 如果n%(n-kmp[k])==0,那么n-kmp[k] ...

  5. MaxCompute 最新特性介绍 | 2019大数据技术公开课第三季

    摘要:距离上一次MaxCompute新功能的线上发布已经过去了大约一个季度的时间,而在这一段时间里,MaxCompute不断地在增加新的功能和特性,比如参数化视图.UDF支持动态参数.支持分区裁剪.生 ...

  6. Django项目:CRM(客户关系管理系统)--19--11PerfectCRM实现King_admin分页显示条数

    登陆密码设置参考 http://www.cnblogs.com/ujq3/p/8553784.html list_per_page = 2 #分页条数 list_per_page = 2 #分页条数 ...

  7. C#中int short Int16 Int32 Int64区别

    Java中没有Int32,Int64,,java中只有int,short,long Java中int就代表Int32 ,short就代表Int16,long就代表Int64 首先,几个基本的关键字: ...

  8. Git.之.最小化配置

    Git.之.最小化配置 做一个全局的用户配置,便于以后提交代码等,记录当前操作的用户. ## 添加配置 # git config [--local | --global | --system] use ...

  9. python Pandas文件读写

  10. 关于memset的使用

    有些oj上的G++支持 cstdio的memset,有些则支持stdio.h中的memset(划掉) 这两个头文件关系比较复杂, 具体我也说不清...按照c++文档中的说法,stdio已经deprec ...