博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu-4309(网络流)
阅读量:5013 次
发布时间:2019-06-12

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

2012多校联合赛第一场,第十题。

先不考虑可以修复的桥的性质, 则可以将模型简化为n个点的人通过有通过人数上限的有向边,到达一些有人数上限的特殊的边(隧道)。

可以建立最大流模型来求解, 增加一个源点S,和一个汇点T。 S向每个有人的点,连一条容量为人数的边, 图中普通的u->v的有向边,连一条u->v的流量为无穷的边, 桥的流量则为1。 对于隧道,每个隧道可以虚拟出一个点,如u->v的隧道,可以虚拟一个点x,连接u->x,x->v的流量无穷的边, 和x->T的流量为隧道人数上限的边, 求解最大流即可得到最大人数。

现在考虑桥的问题,题目中说明了桥最多只有12座,故可以2^12枚举修复哪些桥,不修复的桥没有花费,连接的边流量为1,要修复的桥则计算花费,边的流量为无穷,这样进行2^12次最大流就可以得到最优解。

 

看了题解后,建图,1Y。

2^12枚举,对桥建边很戏剧,用递归,很好玩。

发现我现在的编程状态很好,200行编下来,基本上想到什么就能编出来什么,网络流,递归,枚举。。以后只要相信自己就好。

相信自己的编码能力!!!

View Code
/*Problem : 4309 ( Seikimatsu Occult Tonneru )     Judge Status : AcceptedRunId : 6291376    Language : G++    Author : 2010201211Time : 1687MS Memory : 608K*/#include 
#include
#include
using namespace std;#define E 30000#define V 1102#define inf 0xffffstruct Edge{ int u,v,c,next;}edge[E];int n,m,cnt;int cou;int dist[V];int head[V];int que[V];int sta[V];void init(){ cnt=0; memset(head,-1,sizeof(head));}void addedge(int u,int v,int c){ edge[cnt].u=u;edge[cnt].v=v;edge[cnt].c=c; edge[cnt].next=head[u];head[u]=cnt++; edge[cnt].u=v;edge[cnt].v=u;edge[cnt].c=0; edge[cnt].next=head[v];head[v]=cnt++;}int dinic(int s,int t){ int ans=0; while(true){ int left,right,u,v; memset(dist,-1,sizeof(dist)); left=right=0; que[right++]=s; dist[s]=0; while(left
0 && dist[v]==-1){ dist[v]=dist[u]+1; que[right++]=v; if(v==t){ left=right; break; } } } } if(dist[t]==-1) break; int top=0; int now=s; while(true){ if(now!=t){ int k; for(k=head[now];k!=-1;k=edge[k].next){ if(edge[k].c > 0 && dist[edge[k].u]+1==dist[edge[k].v]) break; } if(k!=-1){ sta[top++]=k; now=edge[k].v; } else{ if(top==0) break; dist[edge[sta[--top]].v]=-1; now=edge[sta[top]].u; } } else{ int flow=inf,ebreak; for(int i=0;i
edge[sta[i]].c){ flow=edge[sta[i]].c; ebreak=i; } } ans+=flow; for(int i=0;i
> n >> m){ for(int i=1;i<=n;i++){ cin >> p[i]; } r=b=t=0; for(int i=1;i<=m;i++){ cin >> a >> bb >> c >> d; if(d<0){ tunnel[t].u=a; tunnel[t].v=bb; tunnel[t++].c=c; } if(d==0){ road[r].u=a; road[r++].v=bb; } if(d>0){ bridge[b].u=a; bridge[b].v=bb; bridge[b++].c=c; } } memset(fb,0,sizeof(fb)); for(int i=0;i<5000;i++){ res[i].cost=0; res[i].num =0; } cou=0; dfs(0); int minc=inf,maxc=-1; for(int i=0;i
maxc){ maxc=res[i].num; } } for(int i=0;i

 

 

转载于:https://www.cnblogs.com/markliu/archive/2012/07/21/2603044.html

你可能感兴趣的文章
iview树的修改某个节点,树刷新后自动展开你刚才展开的所有节点
查看>>
oracle服务起不来以及无法监听问题解决
查看>>
Mvc--Html.ActionLink()的用法
查看>>
delphi 基础书籍推荐
查看>>
《面向对象程序设计》2018年春学期寒假及博客作业总结
查看>>
iOS开发UI之KVC(取值/赋值) - KVO (观察某个对象的某个属性的改变)
查看>>
1.7 将一个MxN矩阵所有为0的元素所在行和列全部置0
查看>>
删除U盘时提示无法停止‘通用卷’设备的解决方法!!不要每次都硬拔了,对电脑有不小的损害!!!...
查看>>
Java中接口与接口和类之间的关系
查看>>
芯片TPS70925
查看>>
linux shell 发送email 附件
查看>>
人群密度估计 CrowdCount
查看>>
JSON.parse()和JSON.stringify()
查看>>
.net 常用正则表达式
查看>>
Java泛型中的标记符含义:
查看>>
初遇GitHub
查看>>
[C# 网络编程系列]专题八:P2P编程
查看>>
Jsの练习-数组常用方法 -forEach()
查看>>
动态绑定treeview的方法
查看>>
jvm参数
查看>>