题意:

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

最小割 = 最大流

建图非常easy。源点就是1,设置汇点T。

按图中的有向边关系连边。

对于全部的可选择的城市u,连一条u->T的容量为w的边。

跑一遍最大流。即为最小割。

ans = sum - 最小割。

写出方案。就是走一遍bfs。看 哪些满流边(而且边的汇不是T,这是由于这种边是所选的城市扩展的边),打出来就好。

代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
const int N = 1000 + 10 ;
const int inf = 1000000000;
typedef long long ll;
struct Edge
{
int from,to,cap,flow;
};
int n,m,s,t,num,f;
int w[N],use[N];
int vis[2*N],cur[2*N];
vector<int> G[2*N];
vector<Edge> edges;
queue<int> cut;
void init()
{
edges.clear();
for(int i=1;i<=n;i++) G[i].clear();
memset(vis,0,sizeof(vis));
}
int add(int u,int v,int c)
{
edges.push_back((Edge){u,v,c,0});
edges.push_back((Edge){v,u,0,0});
num = edges.size();
G[u].push_back(num-2);
G[v].push_back(num-1);
}
int bfs()
{
int front;
memset(vis,0,sizeof(vis));
vis[s] = 1;
queue<int> q;
q.push(s);
while(!q.empty()){
front = q.front(); q.pop();
for(int i=0;i<G[front].size();i++)
{
Edge& e = edges[G[front][i]];
if(!vis[e.to] && e.cap > e.flow)
{
q.push(e.to);
vis[e.to] = vis[front]+1;
}
}
}
return vis[t];
}
int dfs(int x,int a)
{
if(x==t || a==0) return a;
int f=0,flow=0;
for(int i=0;i<G[x].size();i++){
Edge& e = edges[G[x][i]];
if(vis[e.to]==vis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>0 )
{
flow += f;
e.flow += f;
a -= f;
edges[G[x][i]^1].flow -= f;
if(a==0) break;
}
}
return flow;
}
int dinic()
{
int flow = 0;
while(bfs())
{
memset(cur,0,sizeof(cur));
flow += dfs(s,inf);
}
return flow;
}
void find_cut()
{
while(!cut.empty()) cut.pop();
memset(vis,0,sizeof(vis));
vis[1] = 1;
queue<int> q;
q.push(1);
int front;
while(!q.empty()){
front = q.front(); q.pop();
for(int i=0;i<G[front].size();i++){
Edge& e = edges[G[front][i]];
if(!vis[e.to] && e.cap > e.flow){
vis[e.to] = 1;
q.push(e.to);
}
}
}
for(int i=1;i<=n;i++){
if(vis[i])
for(int j=0;j<G[i].size();j++){
Edge& e = edges[G[i][j]];
if(G[i][j]&1) continue;
if(e.to!=t && !vis[e.to])
cut.push(G[i][j]/2+1);
}
}
return ;
}
void print_cut()
{
int len = cut.size();
int ro;
cout<<len<<" ";
for(int i=1;i<len;i++){
ro = cut.front();
cut.pop();
printf("%d ",ro);
}
ro = cut.front();
cut.pop();
printf("%d\n",ro);
}
int main()
{
int T,cas=0;
scanf("%d",&T);
while(T--){
ll sum = 0;
scanf("%d%d%d",&n,&m,&f);
init();
s = 1; t = n+1;
for(int i=1;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
}
for(int i=1;i<=f;i++){
int u,w;
scanf("%d%d",&u,&w);
add(u,t,w);
sum += w;
}
ll ans = dinic();
find_cut();
printf("Case %d: %lld\n",++cas,sum-ans);
print_cut();
}
return 0;
}

hdu3251 最小割的更多相关文章

  1. HDU3251 Being a Hero(最小割)

    题目大概一个国家n个城市由m条单向边相连,摧毁每条边都有一个费用.现在你可以选择所给的f个城市中的若干个,每个城市选择后都有一定的价值,但首都1号城市必须到达不了你选择的城市,因为你可能需要摧毁一些边 ...

  2. HDU3251 最大流(最小割)

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

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

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

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

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

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

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

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

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

  7. BZOJ3438 小M的作物(最小割)

    题目 Source http://www.lydsy.com/JudgeOnline/problem.php?id=3438 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为 ...

  8. 最大流-最小割 MAXFLOW-MINCUT ISAP

    简单的叙述就不必了. 对于一个图,我们要找最大流,对于基于增广路径的算法,首先必须要建立反向边. 反向边的正确性: 我努力查找了许多资料,都没有找到理论上关于反向边正确性的证明. 但事实上,我们不难理 ...

  9. bzoj1412最小割

    太羞耻了,m n写反了(主要是样例n m相等) 建图方法比较高(ji)端(chu),对于可以加栅栏的地方连上1的边,然后求最小割即可 为了让代码优(suo)美(duan),我写了一个check,避免多 ...

随机推荐

  1. 解决在IE6、7中用height来设定SELECT标签高度无效的兼容性问题

    在IE6.7中用height来设定SELECT标签高度是无效的,宽度的话各浏览器设置都是一致的,解决方法就是在select外嵌套两层标签,一层用来遮挡select的默认边框(在IE6.7中设置bord ...

  2. dom方法insertAfter的实现

    在dom的原生api中,只用insertBefore,没有insertAfter,借助原有的api,可以模拟一个insterAfter. function insterAfter(newElement ...

  3. APIO2018 题解

    坑了好久,补一补. 话说我当时去参加 $APIO2018$ 了,不过纯粹打铁…… 我的程序交道人家毛子的网站上, $c++14$ 编译器不停地给我编 $RE$,只记得好像是结构体排序的问题(删掉那个排 ...

  4. hibernate 4.3 在使用获取数据获取不到数据库中最新变更的数据问题解决

    hibernate 4.3 在使用获取数据获取不到数据库中最新变更的数据问题解决,应该是因为缓存问题 问题过程和现象: 查询一个数据列表=>数据库中手动update了数据=>刷新页面,数据 ...

  5. Atcoder CODE FESTIVAL 2017 qual B E - Popping Balls 组合计数

    题目链接 题意 \(A+B\)个球排成一行,左边\(A\)个为红球,右边\(B\)个为蓝球. 最开始可以选择两个数\(s,t\),每次操作可以取左起第\(1\)或\(s\)或\(t\)个球.问有多少种 ...

  6. sync fsync fdatasync

    传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速 缓存,大多数磁盘I/O都通过缓冲进行.当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队 ...

  7. 递归,回溯,DFS,BFS的理解和模板

    LeetCode 里面很大一部分题目都是属于这个范围,例如Path Sum用的就是递归+DFS,Path Sum2用的是递归+DFS+回溯 这里参考了一些网上写得很不错的文章,总结一下理解与模板 递归 ...

  8. PHP实现自定义中奖和概率算法

    最近玩<QQ飞车手游>,出了一款点券A车,需要消耗抽奖券抽奖,甚是激动,于是抽了几次,没想到中的都是垃圾道具,可恨可叹~~ 这几天项目中也涉及到了类似的概率操作,于是思考了一下,简单分装了 ...

  9. Win10下 tensorflow gpu版安装

    准备: 系统环境: windows10 + Anaconda3 + Pycharm (1)环境配置: 打开Anaconda Prompt,输入清华仓库镜像,这样更新会快一些: 输入: conda co ...

  10. Python语言 介绍

    一.python介绍python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语 ...