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 ...
随机推荐
- js获取中国日期-农历
/* var bsYear; var bsDate; var bsWeek; var arrLen=8; //数组长度 var sValue=0; //当年的秒数 var dayiy=0; //当年第 ...
- FineUI第二天
原博文http://www.cnblogs.com/sanshi/archive/2012/02/12/2347789.html 1.首先复制extJS的文件夹到根目录. 2.引用程序集 3.配置配置 ...
- unity3d iPhone文件目录介绍
原地址:http://cl314413.blog.163.com/blog/static/190507976201210259126559/ 如何查看iPhone文件存放目录?首先需要越狱,越狱后打开 ...
- App开发到App Store上架,发布流程。
http://blog.csdn.net/wojsg001/article/details/12005887 App开发到App Store上架,发布流程. 分类: IOS2013-09-25 11 ...
- 修改 ~/.bashrc显示 git 当前分支
vim ~/.bashrc # git branch show configuration PS1="\\w:\$(git branch 2>/dev/null | grep '^*' ...
- 栈应用hanoi
/* 课本p54页*/ #include<stdio.h> #include <iostream> using namespace std; void move(int n, ...
- Linux Tomcat 简介
如今,基于Web的应用越来越多,传统的Html已经满足不了如今的需求.我们需要一个交互式的Web,于是便诞生了各种Web语言.如Asp,Jsp,Php等.当然,这些语言与传统的语言有着密切的联系,如P ...
- python遍历数组的两种方法
第一种,最常用的,通过for in遍历数组 1 2 3 4 5 6 7 8 colours = ["red","green","blue"] ...
- Eclipse 输入提示设置
提升eclipse工具的效率是提升开发效率很重要的一个环节,然而java函数之多你不可能完全记住.eclipse默认打个“.”号后会有相应的提示,然而这略显笨拙.只需要对eclipse进行简单的配置便 ...
- iOS block 声明时和定义时的不同格式
今天写程序时,在实现一个block时总提示格式错误,对比api的block参数格式,没发现错误.后来查阅了资料,发现这两个格式是不同的! 具体格式见下方 NSString * (^testBlock) ...