HDU 4067 Random Maze
意甲冠军:
一个“随机图”它被定义为具有以下性质如:
一个入口和一个出口
有向图
对于入口 出度比入度大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的更多相关文章
- HDU 4067 hdoj 4067 Random Maze 最小费用流
给出n个点,m条边,入口s和出口t,对于每条边有两个值a,b,如果保留这条边需要花费:否则,移除这条边需要花费b. 题目要求用最小费用构造一个有向图满足以下条件: 1.只有一个入口和出口 2.所有路都 ...
- Random Maze HDU - 4067(预定义状态建边(贪心建边))
Random Maze Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- HDU 4035:Maze(概率DP)
http://acm.split.hdu.edu.cn/showproblem.php?pid=4035 Maze Special Judge Problem Description When w ...
- hdu 4067(最小费用最大流)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4067 思路:很神奇的建图,参考大牛的: 如果人为添加t->s的边,那么图中所有顶点要满足的条件都 ...
- 【HDU】4035 Maze
http://acm.hdu.edu.cn/showproblem.php?pid=4035 题意:给一棵n个节点的树,每个节点有值k[i]和e[i],分别表示k[i]概率走向1号节点,e[i]概率获 ...
- HDU 4579 Random Walk (解方程组)
Random Walk Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65535/65536 K (Java/Others)Total ...
- HDU4067 Random Maze(最小费用最大流)
题目大概说,给一张图,删除其中一些单向边,使起点s出度比入度多1,终点t入度比出度多1,其他点出度等于入度.其中删除边的费用是bi,保留边的费用是ai,问完成要求最小的费用是多少. 一开始我想到和混合 ...
- 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 . ...
- 【转载】图论 500题——主要为hdu/poj/zoj
转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...
随机推荐
- 〖Groovy〗语言使用贴士(Tips)(转)
[Groovy]是一门运行在[JVM]之上的动态语言.由[James Strachan]和[Bob McWhirter]于2003年启动开发,之后于2004年3月成为[JSR 241](Java Sp ...
- hotmail邮箱pop3server设置方法
hotmail邮箱 的POP3/SMTP功能仅仅向Hotmail Plus的用户开放,普通用户想要使用这一功能的话,得进行一些特别的设置.如今这一功能总算面向全部的用户开放了,虽然微软官方还没宣布这一 ...
- Java解惑七:很多其它类之谜
谜题66 继承的问题. 对于实例方法:命名同样时,子类会覆写父类的方法,且訪问权限至少和父类一样大. 对于域:命名同样时,子类会隐藏父类的域,且訪问权限随意. 谜题67 不要重用库中的类名. 谜题68 ...
- CentOS 6.4 文件夹打开方式
CentOS 6.4 文件夹打开方式 在CentOS 6.4中,双击文件夹,默认会在新窗口中打开文件夹,没有路径.前进.后退这样的按钮,如果一个文件夹的路径很深,则需要打开n多的窗口才能找到最终想要的 ...
- A Game of Thrones(0) - PROLOGUE
"We should start back", Gared urged as the woods began to grow dark around them. "The ...
- HiPAC高性能规则匹配算法之查找过程
收到一封邮件,有位朋友认为我误解了nf-HiPAC.如此的一个高性能算法怎能被什么传统的hash,tree之类的胁迫.是啊.HiPAC是一个非常猛的算法.文档也比較少,这就更加添加了其神奇感,可是这决 ...
- HT for Web嵌入QtWebKit的client解决方式
HTML5已经足够强大,但非常多应用还是须要独立桌面client的解决方式,毕竟能操作本地文件等功能还是非常多工具类软件短期内无法全然採用云方案替代. 近期Adobe公布的http://bracket ...
- Android规范发展
一.Android 编码规范 1.java 代码中不出现中文.最多凝视中能够出现中文 2.局部变量命名.静态成员变量命名 仅仅能包括字母,单词首字母出第一个外,都为大写,其它字母都为小写 3.常量命名 ...
- 站点搭建从零開始(四) server的配置
原文发表在我的个人站点,欢迎大家訪问~转载请保留本段,或注明原文:http://www.hainter.com/website-primer-4 域名解析设置好了,通常我们就能够訪问我们的网站了,上篇 ...
- android AIDL RPC 机制
AIDL 这是接口文件的叙述性说明,为了实现android 上述平台RPC ,aapt 在编译时自己主动按照该规则IPC 的接口和对象,作为一个用户只需要 实现在服务侧的界面 2 在clientbin ...