意甲冠军:

一个“随机图”它被定义为具有以下性质如:

一个入口和一个出口

有向图

对于入口  出度比入度大1

对于出口  入度比出度大1

对于其它点  入度等于出度

现给出一幅有向图  每条边有2个决策——留下、扔掉  分别花费a和b  问  假设用最少的费用改造出“随机图”

思路:

网络流不错的题目  假设做过“混合图欧拉回路”(后文把这个问题成为p)那个zoj的题的话  这道题会有启示

来回顾p的做法  先将无向边任意定向  再利用度来将点划分成二分图  利用无向边建边  利用度连接这些点与源汇  然后做maxflow  满流则有解

“任意定向”启示我们本题也能够对边进行一定的处理  因此我们能够先比較a和b  取当中小的状态  这样得到的一定是费用最小的决策  但不保证是“随机图”  那么此时我们仅仅须要改变决策  在费用最小的情况下达到“随机图”  此时想到了费用流

“利用度构图”启示我们相同讨论  in>out  in==out  in<out  的三种点(事实上入口和出口能够稍加处理归并到一般点中去)  对于 in>out 的点  我们与S连边  对于 in<out 的点  我们与T连边  容量即为|in-out|  来表示这个点须要修正的度数

尽管我们的图不是二分图  可是层次关系仍然明显

我们将m条输入的边依照a和b的大小关系  分别建边u->v 容量1 费用b-a 表示将边从留下状态改为扔掉状态  反之亦然

那么此时流量就表示通过更改边的策略  能将多少“度”平衡掉  也就是说  假设maxflow满流  则能够构成“随机图”

剩下的就是最小费用  非常明显就是刚才建边的费用之和  最后费用+“随即定向”时的最小花费就是答案

PS:要尽量去理解网络流中“流”的实际意义  想办法构造图

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<cmath>
using namespace std;
typedef long long LL;
#define N 110
#define M 2010
#define inf (1<<20) int casnum, cas, n, m, s, t, S, T, ans, tot, flow, totflow, cost;
int head[N], pre[N], vis[N], dis[N], din[N], dout[N], temp[N];
struct edge {
int u, v, w, c, next;
} ed[N * M];
queue<int> qu; void init() {
S = 0;
T = n + 1;
ans = 0;
tot = 0;
totflow = 0;
flow = 0;
cost = 0;
memset(head, -1, sizeof(head));
memset(din, 0, sizeof(din));
memset(dout, 0, sizeof(dout));
} void add(int U, int V, int W, int C) {
ed[tot].u = U;
ed[tot].v = V;
ed[tot].w = W;
ed[tot].c = C;
ed[tot].next = head[U];
head[U] = tot++; ed[tot].u = V;
ed[tot].v = U;
ed[tot].w = 0;
ed[tot].c = -C;
ed[tot].next = head[V];
head[V] = tot++;
} int spfa() {
int i, u, v;
while (!qu.empty())
qu.pop();
for (i = 0; i <= T; i++) {
vis[i] = 0;
dis[i] = inf;
pre[i] = -1;
}
qu.push(S);
vis[S] = 1;
dis[S] = 0;
while (!qu.empty()) {
u = qu.front();
qu.pop();
vis[u] = 0;
for (i = head[u]; ~i; i = ed[i].next) {
if (!ed[i].w)
continue;
v = ed[i].v;
if (dis[v] > dis[u] + ed[i].c) {
dis[v] = dis[u] + ed[i].c;
pre[v] = i;
if (!vis[v]) {
vis[v] = 1;
qu.push(v);
}
}
}
}
return dis[T] != inf;
} void mcmf() {
int i, tmp;
while (spfa()) {
tmp = inf;
for (i = pre[T]; ~i; i = pre[ed[i].u]) {
if (tmp > ed[i].w)
tmp = ed[i].w;
}
for (i = pre[T]; ~i; i = pre[ed[i].u]) {
ed[i].w -= tmp;
ed[i ^ 1].w += tmp;
cost += tmp * ed[i].c;
}
flow += tmp;
}
} struct input {
int u, v, a, b;
} f[M]; int main() {
int i, u, v, a, b;
scanf("%d", &casnum);
for (cas = 1; cas <= casnum; cas++) {
scanf("%d%d%d%d", &n, &m, &s, &t);
init();
for (i = 1; i <= m; i++) {
scanf("%d%d%d%d", &u, &v, &a, &b);
f[i].u = u;
f[i].v = v;
f[i].a = a;
f[i].b = b;
if (a < b) { //stay
ans += a;
din[v]++;
dout[u]++;
add(u, v, 1, f[i].b - f[i].a);
} else {
ans += b; //remove
add(v, u, 1, f[i].a - f[i].b);
}
}
for (i = 1; i <= n; i++) {
temp[i] = dout[i] - din[i];
if (i == s)
temp[i]--;
else if (i == t)
temp[i]++;
if (temp[i] > 0) {
add(S, i, temp[i], 0);
totflow += temp[i];
} else if (temp[i] < 0)
add(i, T, -temp[i], 0);
}
mcmf();
printf("Case %d: ", cas);
if (totflow == flow)
printf("%d\n", ans + cost);
else
printf("impossible\n");
}
return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

HDU 4067 Random Maze的更多相关文章

  1. HDU 4067 hdoj 4067 Random Maze 最小费用流

    给出n个点,m条边,入口s和出口t,对于每条边有两个值a,b,如果保留这条边需要花费:否则,移除这条边需要花费b. 题目要求用最小费用构造一个有向图满足以下条件: 1.只有一个入口和出口 2.所有路都 ...

  2. Random Maze HDU - 4067(预定义状态建边(贪心建边))

    Random Maze Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  3. HDU 4035:Maze(概率DP)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=4035 Maze Special Judge Problem Description   When w ...

  4. hdu 4067(最小费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4067 思路:很神奇的建图,参考大牛的: 如果人为添加t->s的边,那么图中所有顶点要满足的条件都 ...

  5. 【HDU】4035 Maze

    http://acm.hdu.edu.cn/showproblem.php?pid=4035 题意:给一棵n个节点的树,每个节点有值k[i]和e[i],分别表示k[i]概率走向1号节点,e[i]概率获 ...

  6. HDU 4579 Random Walk (解方程组)

    Random Walk Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65535/65536 K (Java/Others)Total ...

  7. HDU4067 Random Maze(最小费用最大流)

    题目大概说,给一张图,删除其中一些单向边,使起点s出度比入度多1,终点t入度比出度多1,其他点出度等于入度.其中删除边的费用是bi,保留边的费用是ai,问完成要求最小的费用是多少. 一开始我想到和混合 ...

  8. hdu 4579 Random Walk 概率DP

    思路:由于m非常小,只有5.所以用dp[i]表示从位置i出发到达n的期望步数. 那么dp[n] = 0 dp[i] = sigma(dp[i + j] * p (i , i + j)) + 1 .   ...

  9. 【转载】图论 500题——主要为hdu/poj/zoj

    转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

随机推荐

  1. WPF-20:richtextbox相关操作(转)

    WPF中的richtextbox与winform中的richtextbox的使用不同,看看下面的基本操作: 一.取出richTextBox里面的内容  (1)将richTextBox的内容以字符串的形 ...

  2. 在内网架设一个可供外网登录的ftpserver

    ftpserver是使用比較寻常的server,可是IP资源是有限的.那么怎么让内网的server給外网的用户提供服务了? 首先须要找一个FTPserver程序,我在这边使用pure-ftpd-mys ...

  3. iText操作word文档总结

    操作word文档的工具有很多,除了iText之外还有POI,但是POI擅长的功能是操作excel,虽然也可以操作word,但是能力有限,而且还有很多的bug,技术并不成熟,下面就重点介绍一种操作wor ...

  4. Xcode6在10.9.4上面crash解决

    具体请看我的evernote 这里: 在10.9.4系统上面直接安装xcode6的beta3.和平时一样, 1.将beta3拖拽到application文件夹中. 2.等待copy完毕,执行xcode ...

  5. WPF实现无窗体鼠标跟随

    原文:WPF实现无窗体鼠标跟随 上次的弹力模拟动画实现后,我觉得可以把这个弄得更好玩一些,我们可以让小球实时跟随着鼠标,并且还可以让窗口完全消失,让小球在桌面上飞来飞去. 这只需要一些简单的修改就可以 ...

  6. Python学习入门基础教程(learning Python)--3.1Python的if分支语句

    本节研究一下if分支语句. if分支语句是Python下逻辑条件控制语句,用于条件执行某些语句的控制操作,当if后的条件conditon满足时,if其下的语句块被执行,但当if的控制条件condito ...

  7. 树上第k小,可持久化线段树+倍增lca

    给定一颗树,树的每个结点都有权值, 有q个询问,每个询问是 u v k ,表示u到v路径上第k小的权值是多少. 每个结点所表示的线段树,是父亲结点的线段树添加该结点的权值之后形成的新的线段树 c[ro ...

  8. 构建自己的Java并发模型框架

    Java的多线程特性为构建高性能的应用提供了极大的方便,可是也带来了不少的麻烦.线程间同步.数据一致性等烦琐的问题须要细心的考虑,一不小心就会出现一些微妙的,难以调试的错误. 另外.应用逻辑和线程逻辑 ...

  9. Chromium Graphics: GPUclient的原理和实现分析之间的同步机制-Part II

    摘要:Part I探析GPUclient之间的同步问题,以及Chromium的GL扩展同步点机制的基本原理.本文将源码的角度剖析同步点(SyncPoint)机制的实现方式. 同步点机制的实现主要涉及到 ...

  10. minihomepage.exe 百度视频迷你主页

    百度视频最近动作可真.延续"DHot.exe 热点资讯"之后,又在桌面上出现了Tips窗体,例如以下图: 尽管是迷你的,可还是把其他桌面图标给挡了啊! 突然出来这么个窗体.我还以为 ...