题目大概一个国家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(最小割)的更多相关文章

  1. HDU 3251 Being a Hero(最小割+输出割边)

    Problem DescriptionYou are the hero who saved your country. As promised, the king will give you some ...

  2. HDU3251 最大流(最小割)

    Being a Hero Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...

  3. Being a Hero (hdu 3251 最小割 好题)

    Being a Hero Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  4. hdu3251 最小割

    题意: 给n个城市,m条有向边.每条边有权值,如今有些城市能够选择得到.可选的城市有一个价值.可是要满足从1到达不了这些城市,为了满足要求能够去掉一些边,须要花费边的权值,问终于得到的最大价值是多少, ...

  5. [HDU 3521] [最小割] Being a Hero

    题意: 在一个有向图中,有n个点,m条边$n \le 1000 \And \And  m \le 100000$ 每条边有一个破坏的花费,有些点可以被选择并获得对应的金币. 假设一个可以选的点是$x$ ...

  6. 最大流&最小割 - 专题练习

    [例1][hdu5889] - 算法结合(BFS+Dinic) 题意 \(N\)个点\(M\)条路径,每条路径长度为\(1\),敌人从\(M\)节点点要进攻\(1\)节点,敌人总是选择最优路径即最短路 ...

  7. BZOJ 1391: [Ceoi2008]order [最小割]

    1391: [Ceoi2008]order Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1509  Solved: 460[Submit][Statu ...

  8. BZOJ-2127-happiness(最小割)

    2127: happiness(题解) Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1806  Solved: 875 Description 高一 ...

  9. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

随机推荐

  1. 【Docker】来自官方映像的 6 个 Dockerfile 技巧

    本文将根据我从官方镜像学到的经验,讲解编写Dockerfile的技巧.   1. 选择Debian  官方镜像的大多数Dockerfile,不管是直接还是通过其他镜像,都是基于Debian的.Dock ...

  2. (转)Sublime Text 2 2.0.2 序列号

    ----- BEGIN LICENSE -----Andrew WeberSingle User LicenseEA7E-855605813A03DD 5E4AD9E6 6C0EEB94 BC9979 ...

  3. 29.调整数组顺序使奇数位于偶数前面[ReOrderArray]

    [题目] 输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分.要求时间复杂度为O(n). [分析] 如果不考虑时间复杂度,最简单的思路应该是从头扫描这个 ...

  4. 安装完mysql后用root不能su成mysql

    现象: debian的机器用aptitude install mysql-server-5.1 后,用id mysql 可看出已经建了mysql用户,但是用root来su mysql 不成功,/var ...

  5. iOS category中的所谓属性 和 从xib初始化对象的方法 以及类扩展

    今天在编码时遇到以下代码 @interface UITextField (TCCustomFont) @property (nonatomic, copy) NSString* fontName; @ ...

  6. Java最常用的变量定义汇总

    Java最常用的数据类型有基本数据类型,字符串对象,数组,基本数据类型又分为:数值型(包括整形和浮点型),字符型,布尔型,下面用一个简单的程序把这些数据类型汇总一下 public class Java ...

  7. July 27th, Week 31st Wednesday, 2016

    Don't let yesterday take up too much of today. 别让昨天的事情占据今天太多时间. Learn from yesterday, but don't let ...

  8. 一、HTML和CSS基础--HTML+CSS基础课程--第5部分

    第九章 CSS盒模型 元素分类
: 在讲解CSS布局之前,我们需要提前知道一些知识,在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素. 常用的 ...

  9. iptables 无法连外网

    [root@v01-svn-test-server ~]# service iptables status Table: filter Chain INPUT (policy DROP) num ta ...

  10. List、Map、Set

    这样的题属于随意发挥题:这样的题比较考水平,两个方面的水平:一是要真正明白这些内容,二是要有较强的总结和表述能力.如果你明白,但表述不清楚,在别人那里则等同于不明白. 首先,List与Set具有相似性 ...