Being a Hero (hdu 3251 最小割 好题)
Being a Hero
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1211 Accepted Submission(s): 381
Special Judge
But don't get too excited. The cities you take should NOT be reachable from the capital -- the king does not want to accidentally enter your area. In order to satisfy this condition, you have to destroy some roads. What's worse, you have to pay for that --
each road is associated with some positive cost. That is, your final income is the total value of the cities you take, minus the total cost of destroyed roads.
Note that each road is a unidirectional, i.e only one direction is available. Some cities are reserved for the king, so you cannot take any of them even if they're unreachable from the capital. The capital city is always the city number 1.
can take. Cities are numbered 1 to n. Each of the following m lines contains three integers u, v, w, denoting a road from city u to city v, with cost w. Each of the following f lines contains two integers u and w, denoting an available city u, with value w.
1 to m in the same order they appear in the input. If there are more than one solution, any one will do.
2
4 4 2
1 2 2
1 3 3
3 2 4
2 4 1
2 3
4 4
4 4 2
1 2 2
1 3 3
3 2 1
2 4 1
2 3
4 4
Case 1: 3
1 4
Case 2: 4
2 1 3
pid=3259" target="_blank">3259
pid=3258" target="_blank">3258
pid=3257" target="_blank">3257
3256 3255题意:n个点m条边的有向图,每条边有破坏话花费,如今国王在城市1,要分配给英雄一些城市。分配的原则是:仅仅能在规定的f个城市中选若干个。这f个城市每一个都有一个获利。被选择的城市要与国王所在的城市1隔离,所以选定后要花费一些费用来破坏边。问最后获利的最大值是多少,而且输出要破坏的边的序号。
思路:这个题拿到手之后非常久没有思路。由于图上既有获利又有花费,不知道怎么建图。无奈仅仅好求助网上神牛。
加入汇点T,原图上的单向边依次建边,容量为花费,同意选择的f个点向汇点T连边。容量为点上权值。
跑一遍最小割得到花费值cost,然后用总的能获得利润(就是f个点的权值之和)减去cost就是答案。那么如何确定哪条边是割边呢?从源点S在残留网络中dfs遍历能走到的点。那么这些点就是属于S集,其它剩下的点就属于T集了。然后推断边的两个点所属的集合。假设属于不同的集合那么这条边就是割边。
这样建边就全然转换成费用了,对于原图上的边假设被割到,那么这条边就是要破坏的,对于和汇点相连的边假设被割到。那么这个城市就是不能选的,最后最小割就是最小费用,感觉这样非常巧妙。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define DBG pf("Hi\n")
typedef long long ll;
using namespace std; #define INF 0x3f3f3f3f
#define mod 1000000009
const int maxn = 1005;
const int MAXN = 2005;
const int MAXM = 200010;
const int N = 1005; int n,m,f; struct Edge
{
int to,next,cap,flow;
}edge[MAXM]; int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN]; void init()
{
tol=0;
memset(head,-1,sizeof(head));
} //加边,单向图三个參数。双向图四个參数
void addedge(int u,int v,int w,int rw=0)
{
edge[tol].to=v; edge[tol].cap=w; edge[tol].next=head[u];
edge[tol].flow=0; head[u]=tol++;
edge[tol].to=u; edge[tol].cap=rw; edge[tol].next=head[v];
edge[tol].flow=0; head[v]=tol++;
} //输入參数:起点。终点,点的总数
//点的编号没有影响。仅仅要输入点的总数
int sap(int start,int end,int N)
{
memset(gap,0,sizeof(gap));
memset(dep,0,sizeof(dep));
memcpy(cur,head,sizeof(head));
int u=start;
pre[u]=-1;
gap[0]=N;
int ans=0;
while (dep[start]<N)
{
if (u==end)
{
int Min=INF;
for (int i=pre[u];i!=-1;i=pre[edge[i^1].to])
if (Min>edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
for (int i=pre[u];i!=-1;i=pre[edge[i^1].to])
{
edge[i].flow+=Min;
edge[i^1].flow-=Min;
}
u=start;
ans+=Min;
continue;
}
bool flag=false;
int v;
for (int i=cur[u];i!=-1;i=edge[i].next)
{
v=edge[i].to;
if (edge[i].cap-edge[i].flow && dep[v]+1==dep[u])
{
flag=true;
cur[u]=pre[v]=i;
break;
}
}
if (flag)
{
u=v;
continue;
}
int Min=N;
for (int i=head[u];i!=-1;i=edge[i].next)
if (edge[i].cap-edge[i].flow && dep[edge[i].to]<Min)
{
Min=dep[edge[i].to];
cur[u]=i;
}
gap[dep[u]]--;
if (!gap[dep[u]]) return ans;
dep[u]=Min+1;
gap[dep[u]]++;
if (u!=start) u=edge[pre[u]^1].to;
}
return ans;
} bool vis[MAXN];
int out[MAXN]; void dfs(int u)
{
if (vis[u]) return ;
vis[u]=true;
for (int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if (edge[i].cap-edge[i].flow>0)
dfs(v);
}
return ;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
int i,j,t,u,v,w,cas=0;
sf(t);
while (t--)
{
init();
sfff(n,m,f);
for (i=0;i<m;i++)
{
sfff(u,v,w);
addedge(u,v,w);
}
int T=0,all=0;
for (i=0;i<f;i++)
{
sff(u,w);
addedge(u,T,w);
all+=w;
}
printf("Case %d: %d\n",++cas,all-sap(1,T,n+1));
mem(vis,false);
dfs(1);
int cnt=0;
for (i=0;i<2*m;i+=2)
{
if (vis[edge[i^1].to]&&!vis[edge[i].to])
out[cnt++]=i/2;
}
printf("%d",cnt);
for (i=0;i<cnt;i++)
pf(" %d",out[i]+1);
pf("\n");
}
return 0;
}
Being a Hero (hdu 3251 最小割 好题)的更多相关文章
- [HDU 3521] [最小割] Being a Hero
题意: 在一个有向图中,有n个点,m条边$n \le 1000 \And \And m \le 100000$ 每条边有一个破坏的花费,有些点可以被选择并获得对应的金币. 假设一个可以选的点是$x$ ...
- hdu 4289(最小割)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4289 思路:求最小花费,最小割应用,将点权转化为边权,拆点,(i,i+n)之间连边,容量为在城市i的花 ...
- HDU 5889 Barricade(最短路+最小割水题)
Barricade Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
- hdu 5076 最小割灵活运用
这意味着更复杂的问题,关键的事实被抽象出来:每个点,能够赋予既有的值(挑两个一.需要选择,设定ai,bi). 寻找所有和最大.有条件:如果两个点同时满足: 1,:二进制只是有一个不同之处. 2:中的 ...
- Game HDU - 3657(最小割)
Game Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- hdu 1565 最小割
黑白染色,源指向白,黑指向汇,容量都是方格中数的大小,相邻的格子白指向黑,容量为oo,然后求一次最小割. 这个割是一个简单割,如果只选择不在割中的点,那么一种割就和一个选数方案一一对应,割的大小就是不 ...
- hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割
题意:方格取数,如果取了相邻的数,那么要付出一定代价.(代价为2*(X&Y))(开始用费用流,敲升级版3820,跪...) 建图: 对于相邻问题,经典方法:奇偶建立二分图.对于相邻两点连边2 ...
- hdu 3657 最小割(牛逼!!!!)总算理解了
<strong></strong> 转载:http://blog.csdn.net/me4546/article/details/6662959 加颜色的太棒了!!! 在网上看 ...
- hdu 3691最小割将一个图分成两部分
转载地址:http://blog.csdn.net/xdu_truth/article/details/8104721 题意:题给出一个无向图和一个源点,让你求从这个点出发到某个点最大流的最小值.由最 ...
随机推荐
- python基础——8(装饰器)
一.nonlocal关键字 def outer(): num = 0 def inner(): # 如果想在被嵌套的函数中修改外部函数变量(名字)的值 nonlocal num # 将 L 与 E(E ...
- 【ITOO 3】.NET 动态建库建表:实用EF框架提供的codeFirst实现动态建库
导读:在上篇博客中,介绍了使用SQL字符拼接的方式,实现动态建库建表的方法.这样做虽然也能够实现效果,但是,太麻烦,而且,如果改动表结构,字段的话,会对代码修改很多.但是EF给我们提供了一种代码先行的 ...
- 准确率(Precision),召回率(Recall)以及综合评价指标(F1-Measure)
准确率和召回率是数据挖掘中预测,互联网中得搜索引擎等经常涉及的两个概念和指标. 准确率:又称“精度”,“正确率” 召回率:又称“查全率” 以检索为例,可以把搜索情况用下图表示: 相关 不相关 检索 ...
- HDU 3264 区间内的最大最小之差
题目链接:http://poj.org/problem?id=3264 题目大意:在给定一堆牛的数量以及其高度的时候,每次给定一段区间,求这个区间内最高的牛和最矮的牛的高度之差为多少. 可以直接利用R ...
- 【思维+贪心】codeforces Game of the Rows
http://codeforces.com/contest/839/problem/B [题意] 给定n组人,告诉每组人的人数,这些人要在飞机上坐座位 飞机上座位的分布看图可以知道,12 3456 ...
- BZOJ1740: [Usaco2005 mar]Yogurt factory 奶酪工厂
n<=10000天每天Ci块生产一东西,S块保存一天,每天要交Yi件东西,求最少花多少钱. 这个我都不知道归哪类了.. #include<stdio.h> #include<s ...
- FF,chrome与IE的事件处理程序
今天学习了js的事件处理程序,IE与FF,chrome,safari,opera的处理事件方法不同,FF,chrome,safari,opera支持addEventLisener,而addEventL ...
- POJ 1502 水 dij
题意:给N,表示N个节点. 给半个邻接矩阵,本身到本身的距离是0,边是双向的.当两个节点之间没有直接的边连接的时候,用x表示. 问从第一个节点到其他所有节点至少花费的时间. 这题唯一的处理是处理邻接矩 ...
- http 连接失败重连机制
1.我们做web开发时,需要经常使用httpclient来请求http服务,有时为了安全起见,服务提供方会提供多个http地址,这样如果我们请求某个ip出现异常,可以重试其他的ip地址,来尽量保证系统 ...
- [转]图解eclipse 查看原始类出现The jar file rt.jar has no source attachment
原文:http://blog.csdn.net/u011514810/article/details/53196371 ---------------------------------------- ...