题意:有n个点和m条有向边构成的网络。每条边有两个花费:

d:毁坏这条边的花费
b:重建一条双向边的花费

寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到S的路径的费用和 + 重建这些T到S的双向路径的费用和。

思路1:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" align="middle" alt="">

然后这个无源汇带上下界网络流的可行流问题的求解方法见这里~~

建图就是上面说的那样啦~最后推断有没有可行流就是求一下我们所构造的这个新的网络的最大流~然后推断一下这个最大流是否满流~(即推断最大流是否和附加源点的流出总量相等~~)

code:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#include<cstdlib>
using namespace std; #define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define mem(a, b) memset(a, b, sizeof(a)) typedef pair<int,int> pii;
typedef long long LL;
//------------------------------
const int maxn = 210; int n,m; struct Edge{
int to, cap, rev;//终点 容量 反向边
Edge(int to_ = 0, int cap_ = 0, int rev_ = 0){
to = to_;
cap = cap_;
rev = rev_;
}
};
vector<Edge> g[maxn];
int level[maxn];//顶点到源点的距离标号
int iter[maxn]; void add_Edge(int from, int to, int cap){
Edge tmp1(to, cap, g[to].size());
g[from].push_back(tmp1);
Edge tmp2(from, 0, g[from].size()-1);
g[to].push_back(tmp2);
}
void bfs(int s){
memset(level, -1, sizeof(level));
queue<int> q;
level[s] = 0;
q.push(s);
while(!q.empty()){
int v = q.front();
q.pop();
for(int i = 0; i < g[v].size(); i++){
Edge& e = g[v][i];
if(e.cap > 0 && level[e.to] < 0){
level[e.to] = level[v] + 1;
q.push(e.to);
}
}
}
}
int dfs(int v, int t, int f){
if(v == t) return f;
for(int& i = iter[v]; i < g[v].size(); i++){
Edge& e = g[v][i];
if(e.cap > 0 && level[v] < level[e.to]){
int d = dfs(e.to, t, min(e.cap, f));
if(d > 0){
e.cap -= d;
g[e.to][e.rev].cap += d;
return d;
}
} }
return 0;
}
int max_flow(int s, int t){
int flow = 0;
for(;;){
bfs(s);
if(level[t] < 0) return flow;
memset(iter, 0, sizeof(iter));
int f;
while((f = dfs(s, t, INF)) > 0){
flow += f;
}
}
}
//------------------上面是最大流模板部分 正确---------------------- int sum;
int mi[maxn];//这个是用来保存每一个点的 入度-出度 的值,就是论文里的M(i); void init(){
for(int i = 0; i < maxn; i++){//网络流里的清空。不要忘记
g[i].clear();
}
memset(mi, 0, sizeof(mi));
scanf("%d%d",&n,&m);
int u, v, d, b;
for(int i = 1; i <= m; i++){
scanf("%d%d%d%d",&u, &v, &d, &b);
mi[u]-=d; mi[v]+=d;
add_Edge(u, v, b);//加边加上的是每条边的下界值
}
sum = 0;//sum保存的是源点的全部流出流量
for(int i = 1; i <= n; i++){
if(mi[i] < 0) add_Edge(i, n+1, -mi[i]);
else if(mi[i] > 0) {
add_Edge(0, i, mi[i]);
sum += mi[i];
}
}
}
void solve(){
int ans = max_flow(0, n+1);
if(ans == sum) printf("happy\n");
else printf("unhappy\n");
}
int main(){
int t;
int cas = 0;
scanf("%d",&t);
while(t--){
init();
printf("Case #%d: ",++cas);
solve();
}
return 0;
}

思路2:

阔以试想~假设对于全部单一的一个点组成的集合S来说,都不能满足

S到T的路径的费用和 > 毁坏全部T到S的路径的费用和 + 重建这些T到S的双向路径的费用和 的话,那么随意的点的集合构成的S集合也一定并不能满足上述条件~~~反之假设存在集合满足上述条件的话,就一定存在单一的点满足上述条件~~~~

这样我们事实上仅仅用枚举点然后推断就好啦。。。。。

Orz。。。

code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
const int maxn = 205; int n, m; int D[maxn][maxn], B[maxn][maxn];
vector<int> in[maxn], out[maxn]; void init(){
for(int i = 0; i < maxn; i++){
in[i].clear();
out[i].clear();
}
memset(D,0,sizeof(D));
memset(B,0,sizeof(B));
scanf("%d%d",&n,&m);
int u, v, dd, bb;
for(int i = 1; i <= m; i++){
scanf("%d%d%d%d",&u,&v,&dd,&bb);
out[u].push_back(v);
in[v].push_back(u);
D[u][v] = dd;
B[u][v] = bb;
}
}
bool deal(int u){
int x = 0;
for(int i = 0; i < in[u].size(); i++){
int v = in[u][i];
x += D[v][u];
}
int y = 0;
for(int i = 0; i < out[u].size(); i++){
int v = out[u][i];
y = y + D[u][v] + B[u][v];
}
if(y < x) return true;
return false;
}
void solve(){
for(int i = 1; i <= n; i++){
if(deal(i)){
printf("unhappy\n");
return;
}
}
printf("happy\n");
}
int main(){
int t;
int cas = 0;
scanf("%d",&t);
while(t--){
init();
printf("Case #%d: ",++cas);
solve();
}
return 0;
}

hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )的更多相关文章

  1. HDU 4940 Destroy Transportation system(无源汇上下界网络流)

    Problem Description Tom is a commander, his task is destroying his enemy’s transportation system. Le ...

  2. [Ahoi2014]支线剧情[无源汇有下界最小费用可行流]

    3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1538  Solved: 940[Submit][Statu ...

  3. hdu 4940 Destroy Transportation system (无源汇上下界可行流)

    Destroy Transportation system Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 ...

  4. hdu 4940 Destroy Transportation system(水过)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4940 Destroy Transportation system Time Limit: 2000/1 ...

  5. HDU 4940 Destroy Transportation system(无源汇有上下界最大流)

    看不懂题解以及别人说的集合最多只有一个点..... 然后试了下题解的方法http://blog.sina.com.cn/s/blog_6bddecdc0102uzka.html 首先是无源汇有上下界最 ...

  6. HDU 4940 Destroy Transportation system(2014 Multi-University Training Contest 7)

    思路:无源汇有上下界可行流判定, 原来每条边转化成  下界为D  上界为 D+B   ,判断是否存在可行流即可. 为什么呢?  如果存在可行流  那么说明对于任意的 S 集合流出的肯定等于 流入的, ...

  7. ZOJ 2314 Reactor Cooling(无源汇上下界网络流)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2314 题意: 给出每条边流量的上下界,问是否存在可行流,如果存在则输出. ...

  8. sgu 176 上下界网络流最小可行流带输出方案

    算法步骤: 1. 先将原图像最大可行流那样变换,唯一不同的是不加dst->src那条边来将它变成无源无汇的网络流图.直接跑一边超级源到超级汇的最大流. 2. 加上刚才没有加上的那条边p 3. 再 ...

  9. POJ 2396 Budget (上下界网络流有源可行流)

    转载: http://blog.csdn.net/axuan_k/article/details/47297395 题目描述: 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表 ...

随机推荐

  1. HTML5 总结-表单-表单元素

    HTML5 表单元素 HTML5 的新的表单元素: HTML5 拥有若干涉及表单的元素和属性. 本章介绍以下新的表单元素: datalist keygen output 浏览器支持 Input typ ...

  2. 深入select_related与prefetch_related函数

    阅读博客http://blog.jobbole.com/74881/的笔记 在数据库有外键的时候,使用select_related()和prefetch_related()可以很好的减少数据库请求的次 ...

  3. 第二节 EAN 8 码 / EAN 13 码

    EAN码的全名为欧洲商品条码(European Article Number),源於西元1977年,由欧洲十二个工业国家所共同发展出来的一种条码.目前已成为一种国际性的条码系统.EAN条码系统的管理是 ...

  4. struts ModelDriven

    在表单提交的时候传值是这样,name=admin.username name=admin.password,然后在action中定义属性admin生成get和set 也可以实现ModelDriven这 ...

  5. AFNetworking 进行网络监测

    AFNetworking 进行网络监测 引入头文件,创建检测判断BOOL值 // 网络请求的头文件 #import <AFNetworking.h> @interface ViewCont ...

  6. iOS 把图片从Mac本地添加到iOS Simulator中

    [把图片从Mac本地添加到iOS Simulator中] 1. 把图片从Mac本机拖动到iOS Simulator中: 2. iOS Simulator会自动打开Safari去打开对应的图片,然后你用 ...

  7. myeclipse8.5如何注册,转自他出

    Step: 1.建立一个任意名称的Java Project 2.在该工程中建立一个名文MyEclipseGen的Java文件(MyEclipseGen.java) 3.运行下面的代码,会在控制台出现& ...

  8. [Swust OJ 541]--排列字典序问题

    题目链接:http://acm.swust.edu.cn/problem/0541/ Time limit(ms): 2000 Memory limit(kb): 65535 n个元素{1,2,... ...

  9. Android中弹出对话框,AlertDialog关键代码

    写在这里便于以后查看. Android中弹出对话框的关键代码: btn01.setOnClickListener(new OnClickListener() { @Override public vo ...

  10. CPU自制入门——笔记

    最近在看日本人的那本书<CPU自制入门>就开始自己捣鼓.把工程方到QuartusII 里面后发现编译不通过,总是提示找不到头文件.工程的目录架构是这个样子的 而.v文件中的.h 是这么包含 ...