意甲冠军:

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

一个入口和一个出口

有向图

对于入口  出度比入度大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. hdu3038(并查集)

    题目链接 题意:有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已近给出的是矛盾的 分析:sum数组维护着到根节点的距离(即区间和),每次合并x,y,s(a,b分别为x,y的根节点 ...

  2. Android在子线程中更新UI(一)

    MainActivity如下: package cc.testui1; import android.os.Bundle; import android.os.Handler; import andr ...

  3. Memcached在.net中的应用

    一.MemCached下载 服务端下载:http://memcachedproviders.codeplex.com/ client下载:path=/trunk">http://sou ...

  4. Spring in action(Spring实战) 第四版中文翻译

    第一部分 Spring核心 Spring提供了非常多功能,可是全部这些功能的基础是是依赖注入(DI)和面向方面编程(AOP). 第一章 Springing into action 本章包含: Spri ...

  5. 搭建ganglia集群而且监视hadoop CDH4.6

    前言 近期在研究云监控的相关工具,感觉ganglia颇有亮点,能从一个集群总体的角度来展现数据. 但是安装过程稍过复杂,相关依赖稍多,故写此文章与大家分享下. 本文不解说相关原理,若想了解请參考其它资 ...

  6. iOS_ScrollView的自己主动布局

    ScrollView的自己主动布局稍显麻烦.但也是有规律可循, 下面就是仅竖向滑动的scrollView加入约束的固定做法 1.在控制器的view加入一个label.取名做anchor 2.给anch ...

  7. SecureCRT 6.7.1 注冊机 和谐 破解 补丁 方法

    之前一直在用SecureCRT 6.5.3 版本号,和谐补丁也好找,甚至中文版本号也可找到(眼下仅仅找到了SecureCRT.6.2.0) 可是换为 6.7.1 后就怎么也注冊不了了.. 没办法试了各 ...

  8. 使用Visual Studio 2010 创建简单的Silverlight应用程序

    使用Visual Studio 2010 创建简单的Silverlight应用程序 Silverlight是创建动态的引人的RIAs(Rich Internet Application)的新方法.这里 ...

  9. Swift难点-继承中的构造规则实例具体解释

    关于继承中的构造规则是一个难点. 假设有问题,请留言问我. 我的Swift新手教程专栏 http://blog.csdn.net/column/details/swfitexperience.html ...

  10. 局域网连接SQL Server数据库配置

    首先要保证两台机器位于同一局域网内,然后打开配置工具→SQL Server配置管理器进行配置.将MSSQLSERVER的协议的TCP/IP的(IP1.IP2)TCPport改为1433,已启用改为是. ...