博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 1834网络扩容题解
阅读量:5079 次
发布时间:2019-06-12

本文共 2785 字,大约阅读时间需要 9 分钟。

一道不算太难的题目

但是真的很恶心

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

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

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

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

跑费用流就好了

但是!!!!!!!

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

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

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

真的恶心。。。。

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

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

 

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

 

转载于:https://www.cnblogs.com/logeadd/p/8759238.html

你可能感兴趣的文章
Concurrency Kit 0.2.13 发布,并发工具包
查看>>
SQL Relay 0.50 发布,数据库负载均衡器
查看>>
Infinispan 5.3.0.Alpha1 发布
查看>>
设计模式学习笔记——原型模式(Prototype)
查看>>
算法普林斯顿
查看>>
Struts2之类范围拦截器和方法拦截器
查看>>
模型层(练习)
查看>>
XML解析技术研究(一)
查看>>
Qt 学习之路 :使用 QJson 处理 JSON
查看>>
NPOI操作Excel导入导出
查看>>
angularJS 移动端焦点图
查看>>
jvm 这我就能会了 擦
查看>>
实战技能:小小微信支付业务,何必虚惊一场
查看>>
17-1 djanjo进阶-路由,视图,模板
查看>>
Shell脚本8种字符串截取方法总结
查看>>
P3254 圆桌问题
查看>>
MapReduce的运行原理
查看>>
Leetcode: Partition List
查看>>
故障转移
查看>>
清空dataset中的某行某列的数据
查看>>