【HDU 4940】Destroy Transportation system(无源无汇带上下界可行流)
Description
Let’s represent his enemy’s transportation system as a simple directed graph G with n nodes and m edges. Each node is a city and each directed edge is a directed road. Each edge from node u to node v is associated with two values D and B, D is the cost to destroy/remove such edge, B is the cost to build an undirected edge between u and v.
His enemy can deliver supplies from city u to city v if and only if there is a directed path from u to v. At first they can deliver supplies from any city to any other cities. So the graph is a strongly-connected graph.
He will choose a non-empty proper subset of cities, let’s denote this set as S. Let’s denote the complement set of S as T. He will command his soldiers to destroy all the edges (u, v) that u belongs to set S and v belongs to set T.
To destroy an edge, he must pay the related cost D. The total cost he will pay is X. You can use this formula to calculate X:
After that, all the edges from S to T are destroyed. In order to deliver huge number of supplies from S to T, his enemy will change all the remained directed edges (u, v) that u belongs to set T and v belongs to set S into undirected edges. (Surely, those edges exist because the original graph is strongly-connected)
To change an edge, they must remove the original directed edge at first, whose cost is D, then they have to build a new undirected edge, whose cost is B. The total cost they will pay is Y. You can use this formula to calculate Y:
At last, if Y>=X, Tom will achieve his goal. But Tom is so lazy that he is unwilling to take a cup of time to choose a set S to make Y>=X, he hope to choose set S randomly! So he asks you if there is a set S, such that Y<X. If such set exists, he will feel unhappy, because he must choose set S carefully, otherwise he will become very happy.
Input
The first line contains an integer T(T<=200), indicates the number of cases.
For each test case, the first line has two numbers n and m.
Next m lines describe each edge. Each line has four numbers u, v, D, B.
(2=<n<=200, 2=<m<=5000, 1=<u, v<=n, 0=<D, B<=100000)
The meaning of all characters are described above. It is guaranteed that the input graph is strongly-connected.
Output
Sample Input
2
3 3
1 2 2 2
2 3 2 2
3 1 2 2
3 3
1 2 10 2
2 3 2 2
3 1 2 2
Sample Output
Case #1: happy
Case #2: unhappy
In first sample, for any set S, X=2, Y=4. In second sample. S= {1}, T= {2, 3}, X=10, Y=4.
Source
每个点单独作为S集合时,如果存在满足Y<X,就输出unhappy。否则输出happy。
为什么错呢?输出happy时,即两个点单独作为S时,都有Y1>=X1,Y2>=X2,如果两个点之间没有边,它们一起作为S时,X=X1+X2,Y=Y1+Y2,则Y>=X;但是如果两个点有边相连,X=X1+X2-(S1到S2的D)-(S2到S1的D),Y=Y1+Y2-(S1到S2的D+B)-(S2到S1的D+B),那么Y+B12+B21>=X,就有可能是Y<X了。当输入
1
4 5
1 4 10 2
4 1 6 2
2 1 1 1
4 3 6 2
3 2 4 2
时,输出的是happy。可是实际上,选择1、4节点,Y=2,X=8,显然是unhappy。
附上非正解代码:(AC了只能说明题目数据太水了)
#include <cstdio>
#include <cstring>
#define N 205
#define sf(x) scanf("%d",&x)
int x[N],y[N];
int main(){
int t;
sf(t);
for(int cas=;cas<=t;cas++){
memset(x,,sizeof x);
memset(y,,sizeof y);
printf("Case #%d: ",cas);
int n,m;
sf(n);
sf(m);
for(int i=;i<=m;i++){
int u,v,d,b;
sf(u);sf(v);sf(d);sf(b);
x[u]+=d;
y[v]+=d+b;
}
int ok=;
for(int i=;i<=n;i++)
if(x[i]>y[i])ok=;
if(ok)puts("happy");
else puts("unhappy");
}
}
正解是无源无汇带上下界判断是否有可行流。
求s到t的最大流,如果源点汇点连接的边全部满流则有可行解。
参考国家集训队论文《一种简易的方法求解流量有上下界的网络中网络流问题》
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
#define N 500
#define M 200001
#define inf 0x3f3f3f3f
struct edge{
int to,next,cap,flow;
}e[M];
int head[N],cnt;
int gap[N],dep[N],cur[N];
void init(){
cnt=;
memset(head, -, sizeof head);
}
void add(int u,int v,int w,int rw=){
e[cnt]=(edge){v,head[u],w,};
head[u]=cnt++;
e[cnt]=(edge){u,head[v],rw,};
head[v]=cnt++;
}
int q[N];
void bfs(int st,int ed){
memset(dep,-,sizeof dep);
memset(gap,,sizeof gap);
gap[]=;
int front=,rear=;
dep[ed]=;
q[rear++]=ed;
while(front!=rear){
int u=q[front++];
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(dep[v]!=-)continue;
q[rear++]=v;
dep[v]=dep[u]+;
gap[dep[v]]++;
}
}
}
int s[N];
int sap(int st,int ed,int n){
bfs(st,ed);
memcpy(cur,head,sizeof head);
int top=;
int u=st;
int ans=;
while(dep[st]<n){
if(u==ed){
int Min=inf;
int inser;
for(int i=;i<top;i++)
if(Min>e[s[i]].cap-e[s[i]].flow){
Min=e[s[i]].cap-e[s[i]].flow;
inser=i;
}
for(int i=;i<top;i++){
e[s[i]].flow+=Min;
e[s[i]^].flow-=Min;
}
ans+=Min;
top=inser;
u=e[s[top]^].to;
continue;
}
bool flag=false;
int v;
for(int i=cur[u];~i;i=e[i].next){
v=e[i].to;
if(e[i].cap-e[i].flow&&dep[v]+==dep[u]){
flag=true;
cur[u]=i;
break;
}
}
if(flag){
s[top++]=cur[u];
u=v;
continue;
}
int Min=n;
for(int i=head[u];~i;i=e[i].next)
if(e[i].cap-e[i].flow &&dep[e[i].to]<Min){
Min=dep[e[i].to];
cur[u]=i;
}
gap[dep[u]]--;
if(!gap[dep[u]])return ans;
gap[dep[u]=Min+]++;
if(u!=st)u=e[s[--top]^].to;
}
return ans;
}
int main(){
int t;
scanf("%d",&t);
for(int cas=;cas<=t;cas++){
printf("Case #%d: ",cas);
int n,m;
scanf("%d%d",&n,&m);
int in[N];
int st=,ed=n+;
memset(in,,sizeof in);
init();
for(int i=;i<=m;i++){
int u,v,d,b;
scanf("%d%d%d%d",&u,&v,&d,&b);
add(u,v,b);
in[v]+=d;
in[u]-=d;
}
int need=;
for(int i=;i<=n;i++){
if(in[i]>){
add(st,i,in[i]);
need+=in[i];
}
else add(i,ed,-in[i]);
}
int ans=sap(st, ed, ed+);
if(need==ans)puts("happy");
else puts("unhappy");
}
}
【HDU 4940】Destroy Transportation system(无源无汇带上下界可行流)的更多相关文章
- hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )
题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到 ...
- HDU 4940 Destroy Transportation system(无源汇上下界网络流)
Problem Description Tom is a commander, his task is destroying his enemy’s transportation system. Le ...
- SGU 194 Reactor Cooling 无源汇带上下界可行流
Reactor Cooling time limit per test: 0.5 sec. memory limit per test: 65536 KB input: standard output ...
- POJ 2396 有源有汇有上下界可行流问题
题意:给一个矩阵,给出每行每列之和,附加一些条件,如第i行第j列数必需大于(小于)多少. 思路题解:矩阵模型,模拟网络流,行.列标号为结点,构图,附加s,t,s连行标(容量上下限每行之和(必需以这个 ...
- HDU 4940 Destroy Transportation system(2014 Multi-University Training Contest 7)
思路:无源汇有上下界可行流判定, 原来每条边转化成 下界为D 上界为 D+B ,判断是否存在可行流即可. 为什么呢? 如果存在可行流 那么说明对于任意的 S 集合流出的肯定等于 流入的, ...
- [ACdream 1211 Reactor Cooling]无源无汇有上下界的可行流
题意:无源无汇有上下界的可行流 模型 思路:首先将所有边的容量设为上界减去下界,然后对一个点i,设i的所有入边的下界和为to[i],所有出边的下界和为from[i],令它们的差为dif[i]=to[i ...
- LOJ [#115. 无源汇有上下界可行流](https://loj.ac/problem/115)
#115. 无源汇有上下界可行流 先扔个板子,上下界的东西一点点搞,写在奇怪的合集里面 Code: #include <cstdio> #include <cstring> # ...
- 2018.08.20 loj#115. 无源汇有上下界可行流(模板)
传送门 又get到一个新技能,好兴奋的说啊. 一道无源汇有上下界可行流的模板题. 其实这东西也不难,就是将下界变形而已. 准确来说,就是对于每个点,我们算出会从它那里强制流入与流出的流量,然后与超级源 ...
- [loj#115] 无源汇有上下界可行流 网络流
#115. 无源汇有上下界可行流 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题 ...
随机推荐
- combobox 属性、事件、方法
一 .combobox 属性.事件.方法公共属性 名称 说明 AccessibilityObject 获取分配给该控件的 AccessibleObject. AccessibleDefaultActi ...
- [转] 如何设置Eclipse的上网代理
from: http://blog.csdn.net/qq635785620/article/details/8191799 不同版本的eclipse有不同的设置方法 方式一: 默认的Eclips ...
- android之android.intent.category.DEFAULT的用途和使用
1.要弄清楚这个问题,首先需要弄明白什么是implicit(隐藏) intent什么是explicit(明确) intent. Explicit Intent明确的指定了要启动的Acitivity , ...
- AngularJs 时间格式化处理
1.AngularJs的controller中格式: var dateAsString = $filter('date')(item_date, "yyyy-MM-dd hh:mm:ss&q ...
- 关于高负载服务器Kernel的TCP参数优化
net.ipv4.tcp_mem 内核分配给TCP连接的内存,单位是Page,1 Page = 4096 Bytes,可用命令查看: #getconf PAGESIZE 4096 net.ipv4.t ...
- 线程 VS 进程
线程是指进程内的一个执行单元,也是进程内的可调度实体. 与进程的区别: (1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间; (2)资源拥有: ...
- C# 断点续传原理与实现
在了解HTTP断点续传的原理之前,让我们先来了解一下HTTP协议,HTTP协议是一种基于tcp的简单协议,分为请求和回复两种.请求协议是由 客户机(浏览器)向服务器(WEB SERVER)提交请求时发 ...
- Delphi项目的构成
Hello.cfg 項目配置文件 Hello.dof 項目選項文件 Hello.dpr 項目文件 Hello.exe 應用程序 Hello.res 資源文件 HelloWorld.dcu 窗口編譯文件 ...
- Android手机浏览器访问本地网络相关问题
为了测试开发的手机网站,常常需要使手机直接访问本地网络. 在这个过程中碰到几个问题,记下来供以后参考 1. 在本地主机运行apache后,使用localhost和127.0.0.1可以访问页面,但使用 ...
- Html5 Egret游戏开发 成语大挑战(三)开始界面
本篇需要在前面的素材准备完毕,才可以开始,使用egret的eui结合代码编辑,快速完成基本的界面搭建,这里写的可能比较细,目的是减少大家对于其中一些操作疑问,我去掉了很多无用的步骤,以最精简的流程来完 ...