HDU3251 Being a Hero(最小割)
题目大概一个国家n个城市由m条单向边相连,摧毁每条边都有一个费用。现在你可以选择所给的f个城市中的若干个,每个城市选择后都有一定的价值,但首都1号城市必须到达不了你选择的城市,因为你可能需要摧毁一些边,这样你的获利就是选择城市的价值和减摧毁边的总花费。问,最大的获利是多少以及摧毁哪些边。
如此建容量网络:首都作为源点,原图中单向边的容量设为摧毁边的费用,所有可以选择的城市与汇点相连容量为选择该城市能获得的价值。
这样这个容量网络的S-T割,就能把首都划分到S集合要选择的划分到T集合二者分开,且其最小割就是最小的需要的耗费,耗费由摧毁边的费用和不选择某城市失去的价值组成,最大获利就是f个城市的价值和-最小割。
题目还要求最小割边集的割边,从源点floodfill得到的就是S集合的点,而所有一个端点在S集合另一端点在T集合的边就是最小割边集中的割边。
- #include<cstdio>
- #include<cstring>
- #include<queue>
- #include<algorithm>
- using namespace std;
- #define INF (1<<30)
- #define MAXN 1111
- #define MAXM 220000
- struct Edge{
- int id,v,cap,flow,next;
- }edge[MAXM];
- int vs,vt,NE,NV;
- int head[MAXN];
- void addEdge(int id,int u,int v,int cap){
- edge[NE].id=id; edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=;
- edge[NE].next=head[u]; head[u]=NE++;
- edge[NE].id=id; edge[NE].v=u; edge[NE].cap=; edge[NE].flow=;
- edge[NE].next=head[v]; head[v]=NE++;
- }
- int level[MAXN];
- int gap[MAXN];
- void bfs(){
- memset(level,-,sizeof(level));
- memset(gap,,sizeof(gap));
- level[vt]=;
- gap[level[vt]]++;
- queue<int> que;
- que.push(vt);
- while(!que.empty()){
- int u=que.front(); que.pop();
- for(int i=head[u]; i!=-; i=edge[i].next){
- int v=edge[i].v;
- if(level[v]!=-) continue;
- level[v]=level[u]+;
- gap[level[v]]++;
- que.push(v);
- }
- }
- }
- int pre[MAXN];
- int cur[MAXN];
- int ISAP(){
- bfs();
- memset(pre,-,sizeof(pre));
- memcpy(cur,head,sizeof(head));
- int u=pre[vs]=vs,flow=,aug=INF;
- gap[]=NV;
- while(level[vs]<NV){
- bool flag=false;
- for(int &i=cur[u]; i!=-; i=edge[i].next){
- int v=edge[i].v;
- if(edge[i].cap!=edge[i].flow && level[u]==level[v]+){
- flag=true;
- pre[v]=u;
- u=v;
- //aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
- aug=min(aug,edge[i].cap-edge[i].flow);
- if(v==vt){
- flow+=aug;
- for(u=pre[v]; v!=vs; v=u,u=pre[u]){
- edge[cur[u]].flow+=aug;
- edge[cur[u]^].flow-=aug;
- }
- //aug=-1;
- aug=INF;
- }
- break;
- }
- }
- if(flag) continue;
- int minlevel=NV;
- for(int i=head[u]; i!=-; i=edge[i].next){
- int v=edge[i].v;
- if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
- minlevel=level[v];
- cur[u]=i;
- }
- }
- if(--gap[level[u]]==) break;
- level[u]=minlevel+;
- gap[level[u]]++;
- u=pre[u];
- }
- return flow;
- }
- bool vis[MAXN];
- void dfs(int u){
- vis[u]=;
- for(int i=head[u]; i!=-; i=edge[i].next){
- int v=edge[i].v;
- if(vis[v] || edge[i].cap==edge[i].flow) continue;
- dfs(v);
- }
- }
- int ans[];
- int main(){
- int t,n,m,f,a,b,c;
- scanf("%d",&t);
- for(int cse=; cse<=t; ++cse){
- scanf("%d%d%d",&n,&m,&f);
- vs=; vt=; NV=n+; NE=;
- memset(head,-,sizeof(head));
- for(int i=; i<=m; ++i){
- scanf("%d%d%d",&a,&b,&c);
- addEdge(i,a,b,c);
- }
- int tot=;
- while(f--){
- scanf("%d%d",&a,&b);
- tot+=b;
- addEdge(,a,vt,b);
- }
- printf("Case %d: %d\n",cse,tot-ISAP());
- memset(vis,,sizeof(vis));
- dfs(vs);
- tot=;
- for(int i=; i<NE; i+=){
- int u=edge[i^].v,v=edge[i].v;
- if(vis[u] && !vis[v] && edge[i].id) ans[tot++]=edge[i].id;
- }
- printf("%d",tot);
- for(int i=; i<tot; ++i) printf(" %d",ans[i]);
- putchar('\n');
- }
- return ;
- }
HDU3251 Being a Hero(最小割)的更多相关文章
- HDU 3251 Being a Hero(最小割+输出割边)
Problem DescriptionYou are the hero who saved your country. As promised, the king will give you some ...
- HDU3251 最大流(最小割)
Being a Hero Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- Being a Hero (hdu 3251 最小割 好题)
Being a Hero Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- hdu3251 最小割
题意: 给n个城市,m条有向边.每条边有权值,如今有些城市能够选择得到.可选的城市有一个价值.可是要满足从1到达不了这些城市,为了满足要求能够去掉一些边,须要花费边的权值,问终于得到的最大价值是多少, ...
- [HDU 3521] [最小割] Being a Hero
题意: 在一个有向图中,有n个点,m条边$n \le 1000 \And \And m \le 100000$ 每条边有一个破坏的花费,有些点可以被选择并获得对应的金币. 假设一个可以选的点是$x$ ...
- 最大流&最小割 - 专题练习
[例1][hdu5889] - 算法结合(BFS+Dinic) 题意 \(N\)个点\(M\)条路径,每条路径长度为\(1\),敌人从\(M\)节点点要进攻\(1\)节点,敌人总是选择最优路径即最短路 ...
- BZOJ 1391: [Ceoi2008]order [最小割]
1391: [Ceoi2008]order Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1509 Solved: 460[Submit][Statu ...
- BZOJ-2127-happiness(最小割)
2127: happiness(题解) Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1806 Solved: 875 Description 高一 ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
随机推荐
- Struts.xml讲解
解决在断网环境下,配置文件无提示的问题我们可以看到Struts.xml在断网的情况下,前面有一个叹号,这时,我们按alt+/ 没有提示,这是因为” http://struts.apache.org/d ...
- 调用python 报R6034 错误
R6034 指的是:"An application has made an attempt to load the C runtime library incorrectly. Please ...
- 反正切函数求圆周率 atan
#define PI atan(1.0)*4 原理:tan ∏/4=1; atan2: 返回给定的 X 及 Y 坐标值的反正切值.反正切的角度值等于 X 轴正方向与通过原点和给定坐标点 (Y坐标, X ...
- MySQL 如何只导出 指定的表 的表结构和数据 ( 转 )
MySQL 如何只导出 指定的表 的表结构和数据 ( 转 ) 2011-01-04 15:03:33 分类: MySQL MySQL 如何只导出 指定的表 的表结构和数据 导出更个库的表结构如下:my ...
- (转载)【Android】ViewGroup全面分析
转载自:http://www.cnblogs.com/lqminn/archive/2013/01/23/2866543.html 一个Viewgroup基本的继承类格式如下: import andr ...
- Sublime Text 2 入门及技巧
看了 Nettuts+ 对 Sublime Text 2 的介绍, 立刻就兴奋了,诚如作者 Jeffrey Way 所说:“<永远的毁灭公爵>都发布了,TextMate 2 还没发”,你还 ...
- linux安装setup工具
如果你的Linux系统是最小化安装的,可能会没有setup命令工具,环境是centos 5.8 安装setup命令工具的步骤. 安装setuptool #yum install setuptool 系 ...
- 17.把字符串转换成整数[atoi]
[题目] 把字符串转换成整数,需要考虑字符串有效性. [代码] C++ Code 123456789101112131415161718192021222324252627282930313233 ...
- 惊魂web应用宕机记一次网站的紧急恢复
这次网站的故障出现的比较突然,没有任何防备,有种突如其来的感觉.这是一台阿里云服务器,采用wdcp的nginx+apache+mysql的方式运行.一位同事在对web目录进行压缩后,由于web目录有很 ...
- WPF 将PPT,Word转成图片
在Office下,PowerPoint可以直接把每张幻灯片转成图片,而Word不能直接保存图片.所以只能通过先转换成xps文件,然后再转成图片. 一.PPT 保存为图片 /// <summary ...