Coding Contest

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 5968    Accepted Submission(s): 1413

Problem Description
A coding contest will be held in this university, in a huge playground. The whole playground would be divided into N blocks, and there would be M directed paths linking these blocks. The i-th path goes from the ui-th block to the vi-th block. Your task is to solve the lunch issue. According to the arrangement, there are sicompetitors in the i-th block. Limited to the size of table, bi bags of lunch including breads, sausages and milk would be put in the i-th block. As a result, some competitors need to move to another block to access lunch. However, the playground is temporary, as a result there would be so many wires on the path.
For the i-th path, the wires have been stabilized at first and the first competitor who walker through it would not break the wires. Since then, however, when a person go through the i - th path, there is a chance of pi to touch
the wires and affect the whole networks. Moreover, to protect these wires, no more than ci competitors are allowed to walk through the i-th path.
Now you need to find a way for all competitors to get their lunch, and minimize the possibility of network crashing.
 
Input
The first line of input contains an integer t which is the number of test cases. Then t test cases follow.
For each test case, the first line consists of two integers N (N ≤ 100) and M (M ≤ 5000). Each of the next N lines contains two integers si and bi (si , bi ≤ 200).
Each of the next M lines contains three integers ui , vi and ci(ci ≤ 100) and a float-point number pi(0 < pi < 1).
It is guaranteed that there is at least one way to let every competitor has lunch.
 
Output
For each turn of each case, output the minimum possibility that the networks would break down. Round it to 2 digits.
 
Sample Input
1
4 4
2 0
0 3
3 0
0 3
1 2 5 0.5
3 2 5 0.5
1 4 5 0.5
3 4 5 0.5
 
Sample Output
0.50
 
Source
 
Recommend
jiangzijing2015
 
 
 /*************************************************************************
> File Name: coding_contest.cpp
> Author: CruelKing
> Mail: 2016586625@qq.com
> Created Time: 2019年09月18日 星期三 10时15分58秒
本题思路: 本题要求使得所有人都找到吃饭的地方且使得网络被破坏的可能性最小,因此
很简单可以看出来是个费用流,但是费用流一般都是统计增广路上的花费的和最小而这里我们
要求的概率为p1 * p2 * p.... * pn最小,因此我们可以想到,可以用对要算的式子取对数就很
容易可以将乘法转换为加法,即我们计算ln(p1) + ln(p2) + ... + ln(pn)然后对结果再取
e的指数(刚算的结果作为指数)很容易就可以求得正解,但是这里我们发现由于我们取得log
底数为e,且概率都是小于1的,因此我们得到费用的值都为负数,这样统计我们得到的是费用
的最大值也即概率的最大值就有错误,所以此时我们可以将问题转换为求解网络不被破坏的
可能行最大的问题,也就是使得(1 - p1) * (1 - p2) * ....* (1 - pn)最大,很容易我们
又可以将其转为log,得到ln(1 - p1) + ln(1 - p2) + ... + ln(1 - pn)最大,同样我们又
可以得到一堆负值,所以我们可以将问题转化非求解原问题的倒数最小的问题,那么很容易
我们就可以得到使得-(ln(1 - p1) + ln(1 - p2) + ... + ln(1 - pn))最小即可,也就是说
我们可以将边的花费设置为 - ln(1 - pi)然后跑费用流就可以了,具体如何建图呢?
我们知道每个结点初始情况可能下有人,而且每个结点还有一个上限,我们首先建立超级源点
s和超级汇点t,对于初始情况下的结点,如果一个结点的s[i] - b[i] > 0那么我们就从s到i
建一条容量为s[i] - b[i]的边,花费为0,如果s[i] - b[i] < 0我们就建一条从i到t的边,
容量为b[i] - s[i],花费为0,又由于第一次踩一根线网络不可能出问题,那我们就拆边,把
原来的边拆为一条容量为1花费为0,另一条容量为c[i] - 1花费为-log(1 - p[i])的边.
ok跑一波费用流.
************************************************************************/ #include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
using namespace std; const int maxn = + , maxm = + , inf = 0x3f3f3f3f;
int n, m, s, t; const double eps = 1e-;
int head[maxn], tot; struct Edge {
int to, flow, cap, next;
double cost;
} edge[maxm << ]; void init() {
memset(head, -, sizeof head);
tot = ;
} void addedge(int u, int v, int cap, double cost) {
edge[tot].to = v; edge[tot].flow = ; edge[tot].cap = cap; edge[tot].cost = cost;
edge[tot].next = head[u]; head[u] = tot ++;
edge[tot].to = u; edge[tot].flow = ; edge[tot].cap = ; edge[tot].cost = -cost;
edge[tot].next = head[v]; head[v] = tot ++;
} int pre[maxn];
double dis[maxn];
bool vis[maxn];
int cnt[maxn]; bool spfa() {
queue<int> que;
for(int i = ; i <= n + ; i ++) {
dis[i] = inf;
vis[i] = false;
pre[i] = -;
cnt[i] = ;
}
cnt[s] = ;
dis[s] = 0.0;
vis[s] = true;
que.push(s);
while(!que.empty()) {
int u = que.front(); que.pop(); vis[u] = false;
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost + eps) {
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if(!vis[v]) {
cnt[v] ++;
vis[v] = true;
que.push(v);
if(cnt[v] > n) return false;
}
}
}
}
if(pre[t] == -) return false;
else return true;
} void mincostmxflow (double &ans) {
while(spfa()) {
int Min = inf;
for(int i = pre[t]; ~i; i = pre[edge[i ^ ].to]) {
if(Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow;
}
for(int i = pre[t]; ~i; i = pre[edge[i ^ ].to]) {
edge[i].flow += Min;
edge[i ^ ].flow -= Min;
ans += edge[i].cost * Min;
}
}
} int main() {
int _case, si, bi, u, v, c;
double pi;
scanf("%d", &_case);
while(_case --) {
init();
scanf("%d %d", &n, &m);
s = , t = n + ;
for(int i = ; i <= n; i ++) {
scanf("%d %d", &si, &bi);
if(si > bi) addedge(s, i, si - bi, 0.0);
else if(si < bi) addedge(i, t, bi - si, 0.0);
}
for(int i = ; i < m; i ++) {
scanf("%d %d %d %lf", &u, &v, &c, &pi);
if(c > ) addedge(u, v, , 0.0);
if(c > ) addedge(u, v, c - , -log2( - pi));
}
double ans = ;
mincostmxflow(ans);
printf("%.2f\n", 1.0 - pow(, -ans));
}
return ;
}
 

2016青岛区域赛.Coding Contest(费用流 + 概率计算转换为加法计算)的更多相关文章

  1. HDU5988 Coding Contest(费用流)

    2016青岛现场赛的一题,由于第一次走过不会产生影响,需要拆点,不过比赛时没想到,此外还有许多细节要注意,如要加eps,时间卡得较紧要注意细节优化等 #include <iostream> ...

  2. UVALive - 7740 Coding Contest 2016 青岛区域赛 (费用流)

    题意:每个点i有\(s_i\)个人和\(b_i\)份食物,每个人都要找到一份食物.现在有M条有向边,从点i到点j,容量为c,第一次走过不要紧,从第二次开始就要承担\(p(0<p<1)\)的 ...

  3. HDU5988 - 2016icpc青岛 - G - Coding Contest 费用流(利用对数化乘为加

    HDU5988 题意: 有n个区域,每个区域有s个人,b份饭.现在告诉你每个区域间的有向路径,每条路有容量和损坏路径的概率.问如何走可以使得路径不被破坏的概率最小.第一个人走某条道路是百分百不会损坏道 ...

  4. Coding Contest(费用流变形题,double)

    Coding Contest http://acm.hdu.edu.cn/showproblem.php?pid=5988 Time Limit: 2000/1000 MS (Java/Others) ...

  5. hdu-5988 Coding Contest(费用流)

    题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Ot ...

  6. HDU 5988 Coding Contest(费用流+浮点数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 题目大意: 给定n个点,m条有向边,每个点是一个吃饭的地方,每个人一盒饭.每个点有S个人,有B盒 ...

  7. HDU 5880 Family View (2016 青岛网络赛 C题,AC自动机)

    题目链接  2016 青岛网络赛  Problem C 题意  给出一些敏感词,和一篇文章.现在要屏蔽这篇文章中所有出现过的敏感词,屏蔽掉的用$'*'$表示. 建立$AC$自动机,查询的时候沿着$fa ...

  8. ACM/ICPC2016 青岛区域赛

    A(hdu5982).(模拟) 题意:输入n对数,将每对数相乘并相加 分析:模拟 B(hdu5983).(模拟) 题意:给你一个二阶魔方,问能否通过一次旋转使得给定魔方的每个面颜色相同 分析:模拟 C ...

  9. ACM-ICPC 2016亚洲区域赛(沈阳站)游记(滚粗记)

    首发于QQ空间和知乎,我在这里也更一下.   前言 以前高中搞竞赛的时候,经常看到神犇出去比赛或者训练之后写游记什么的,感觉萌萌哒.但是由于太弱,就没什么心情好写.现在虽然还是很弱,但是抱着享受的心情 ...

随机推荐

  1. Kafka(华为FusionInsight )操作命令

    华为大数据kafka操作web界面创建角色.用户.用户管理角色进入服务器环境,进入客户端目录/opt/hadoopclient,导入环境变量source bigdata_env.切换用户kinit k ...

  2. 【leetcode】1200. Minimum Absolute Difference

    题目如下: Given an array of distinct integers arr, find all pairs of elements with the minimum absolute ...

  3. Haproxy-4层和7层代理负载实战

    目录 HAProxy是什么 HAProxy的核心能力和关键特性 HAProxy的核心功能 HAProxy的关键特性 HAProxy的安装和运行 安装 运行 添加日志 使用HAProxy搭建L7负载均衡 ...

  4. 14. ClustrixDB 高可用性的最佳实践

    本文档详细介绍了最大化ClustrixDB上运行的应用程序正常运行时间的最佳实践.这涵盖了广泛的主题,从环境需求到变更管理程序,所有这些最终都会影响应用程序的可用性.其中许多是您可能已经熟悉的标准最佳 ...

  5. anaconda 安装caffe,cntk,theano-未整理

    一,anancona 安装 https://repo.anaconda.com/archive/ conda create -n caffe_gpu -c defaults python=3.6 ca ...

  6. jquery odd选择器 语法

    jquery odd选择器 语法 作用::odd 选择器选取每个带有奇数 index 值的元素(比如 1.3.5).index 值从 0 开始,所有第一个元素是偶数 (0).最常见的用法:与其他元素/ ...

  7. 箱排序(Bin Sort)

    1.基本思想 排序过程无须比较关键字,而是通过"分配"和"收集"过程来实现排序.它们的时间复杂度可达到线性阶:O(n). 箱排序也称桶排序(Bucket Sor ...

  8. CodeForces 1200D White Lines

    cf题面 Time limit 1500 ms Memory limit 262144 kB 解题思路 官方题解 1200D - White Lines Let's consider a single ...

  9. Navicat使用与python操作数据库

    一.Navicat使用 1.下载地址: <https://pan.baidu.com/s/1bpo5mqj> 2.测试+链接数据库,新建库 3.新建表,新增字段+类型+约束 4.设计表:外 ...

  10. Oracle-SQL程序优化3

    最近一个星期ETL无论在凌晨或是在中午的JOB执行过程中经常卡住,导致不能按时完成系统引擎的运行,对业务产生影响. 通过生成AWR报告,发现有三条SQL消耗大量的CPU,而且还没有执行完成被终止的.如 ...