2016ACM/ICPC亚洲区青岛站 G
来源:互联网 发布:淘宝标题优化工具软件 编辑:程序博客网 时间:2024/05/21 10:05
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 ui-th block to the vi vi-th block. Your task is to solve the lunch issue. According to the arrangement, there are si si competitors in the i-th block. Limited to the size of table, bi 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 ofpi pi to touch
the wires and affect the whole networks. Moreover, to protect these wires, no more thanci 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.
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
the wires and affect the whole networks. Moreover, to protect these wires, no more than
Now you need to find a way for all competitors to get their lunch, and minimize the possibility of network crashing.
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
Each of the next M lines contains three integers
It is guaranteed that there is at least one way to let every competitor has lunch.
14 42 00 33 00 31 2 5 0.53 2 5 0.51 4 5 0.53 4 5 0.5
0.50
题意:以桌子为节点,每张桌子上有s个选手,b袋食物,要让所有的选手都能吃上食物,然后选手在桌子连成的边 上有容量,而且除了第一次路过以外,有pi的概率破坏现场的网线(跟字面意思)。求所有选手都吃上饭且最小破坏线路的概率。
处理初始节点的时候,建立一个源点跟汇点,让 s - b > 0及选手没饭吃的连源点, s - b < 0 桌子上有饭的连汇点。
概率求我们可以 1 - (最大不破坏线路的概率) = 最小破坏线路的概率 ,用概率来代表花费。
因为求概率是乘,最短(长)路的松弛是加减。。所以取log后再跑最短路,然后最后再开方就好了。
#include <cstdio>#include <cstring>#include <iostream>#include <queue>#include <algorithm>#include <vector>#include <cmath>#define INF 1e9using namespace std;const int maxn = 200 + 10;const double esp = 1e-8;struct Edge { int from, to, cap, flow; double cost; Edge(){} Edge(int f, int t, int c, int fl, double co) : from(f), to(t), cap(c), flow(fl), cost(co){}};struct MCMF { int n,m,s,t; vector<Edge> edges; vector<int> G[maxn]; bool inq[maxn]; //是否在队列 double d[maxn]; //Bellman_ford单源最短路径 int p[maxn]; //p[i]表从s到i的最小费用路径上的最后一条弧编号 int a[maxn]; //a[i]表示从s到i的最小残量 //初始化 void init(int n,int s,int t) { this->n = n, this->s = s, this->t = t; edges.clear(); for (int i = 0; i < n; ++i) G[i].clear(); } //添加一条有向边 void AddEdge(int from, int to, int cap, double cost) { edges.push_back(Edge(from, to, cap, 0, cost)); edges.push_back(Edge(to, from, 0, 0, -cost)); m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } //求一次增广路 bool BellmanFord(int &flow, double &cost) { for (int i = 0; i < n; ++i) d[i] = INF; memset(inq, 0, sizeof(inq)); d[s] = 0, a[s] = INF, inq[s] = true, p[s] = 0; queue<int> Q; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = false; for (int i = 0; i < G[u].size(); ++i) { Edge &e = edges[G[u][i]]; if (e.cap > e.flow && d[e.to] - d[u] - e.cost > esp) { d[e.to] = d[u] + e.cost; p[e.to] = G[u][i]; a[e.to] = min(a[u] ,e.cap - e.flow); if (!inq[e.to]) { Q.push(e.to); inq[e.to] = true; } } } } if (d[t] == INF) return false; flow += a[t]; cost += a[t] * d[t]; int u = t; while (u != s) { edges[p[u]].flow += a[t]; edges[p[u] ^ 1].flow -= a[t]; u = edges[p[u]].from; } return true; } //求出最小费用最大流 double Min_cost() { int flow = 0; double cost = 0.0; while (BellmanFord(flow, cost)); return cost; }}MM;int main() { //freopen("in.txt", "r", stdin); int t; scanf("%d", &t); while (t--) { int n, m; scanf("%d%d", &n, &m); MM.init(n + 5, 0, n + 1); for (int i = 1; i <= n; ++i) { int s, b, temp; scanf("%d%d", &s, &b); temp = s - b; if (temp > 0) { MM.AddEdge(0, i, temp, 0); } else if (temp < 0) { MM.AddEdge(i, n + 1, -temp, 0); } } for (int i = 0; i < m; ++i) { int u, v, w; double cost; scanf("%d%d%d%lf", &u, &v, &w, &cost); if (w - 1 > 0) MM.AddEdge(u, v, w - 1, -log2(1 - cost)); if (w > 0) MM.AddEdge(u, v, 1, 0); } double c; c = MM.Min_cost(); printf("%.2lf\n", 1.0 - pow(2, -c)); }}
阅读全文
0 0
- 2016ACM/ICPC亚洲区青岛站 G
- 2016ACM/ICPC亚洲区青岛站 ABC题题解
- 2016ACM/ICPC亚洲区青岛站【solved:5 / 13】
- 2016 ACM-ICPC 亚洲区(青岛赛区)现场赛
- ACM-ICPC亚洲区域赛青岛站总结
- 2017ACM-ICPC亚洲区域赛(青岛站)
- 2016ACM/ICPC亚洲区沈阳站
- ICPC亚洲区域赛青岛站
- 2017 ACM-ICPC 青岛站
- ACM/ICPC青岛站总结
- 2017 ACM-ICPC 亚洲区(青岛赛区)网络赛 待补
- 2017 ACM-ICPC 亚洲区(青岛赛区)网络赛总结
- 2017 ACM/ICPC 亚洲区域赛 青岛赛区
- HDU5971, 2016ACM/ICPC亚洲区大连站第一题
- HDU5950 2016ACM/ICPC亚洲区沈阳站现场赛
- 2016ACM/ICPC亚洲区大连站【solved:10 / 11】
- 2016ACM/ICPC亚洲区大连站 H
- 2016ACM/ICPC亚洲区大连站 I
- N-Queens:N*N位置行列45'斜线无重复元素
- 谈谈我对Android中Aidl通信的理解
- JSON与XML的区别比较
- isomap mds 实现
- Cat VS Dog HDU
- 2016ACM/ICPC亚洲区青岛站 G
- WebStorm ES6 语法支持设置
- 浅谈<label>与<input>合作的两种方式
- maven与gradle的相互转换
- 快排总结和优化
- 笔试_多线程
- The second
- 关于尝试GUI的简易使用过程中遇到的问题1
- Mysql limit 查询性能优化