Coding Contest
来源:互联网 发布:笑傲江湖 知乎 编辑:程序博客网 时间:2024/06/18 05:58
给定n个点,m条有向边,每个点有学生和食物,要求所有学生通过有向边获得食物(保证有解)。问题是现在每条边都有线路,第一个学生经过的时候不会碰到,之后每个经过这条线路的学生都有pi的几率会碰到线路导致网络崩溃,要求满足条件的同事使得网络崩溃率最低。
首先要求网络崩溃率最简单就是1-不崩溃的几率。建立费用流,首先考虑如何收费。因为费用流权值只能相加,所以考虑把所有的概率取上log之后变成每条边的费用。其次由于是最小费用,我们求不被破坏的概率应该最大,所以每个权值取负值。然后建图,从源点到每个有学生的点建立一条容量为学生数量的边,每个有食物的点到汇点建一条容量为食物的边,费用都为0。对于有向边,考虑拆边,分别是容量为1,费用为0的边(第一个经过学生不破坏的概率是1,取log就是0,正负都一样),随后建容量为cap-1,费用为 -log(1.0-cost)的边,跑费用流就好了。
#include <bits/stdc++.h>using namespace std;const int MAXN = 500;const int MAXM = 50000;const int INF = 0x3f3f3f3f;const double eps = 1e-6;struct Edge { int to, next, cap, flow; double cost;} edge[MAXM];int head[MAXN],tol;int pre[MAXN];double dis[MAXN];bool vis[MAXN];int N, T;//节点总个数,节点编号从0~N-1void init(int n) { N = n; tol = 0; memset(head, -1, sizeof(head));}void addedge(int u,int v,int cap,double cost) { edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;}bool spfa(int s,int t) { queue<int>q; for(int i = 0;i < N;i++) { dis[i] = INF; vis[i] = false; pre[i] = -1; } dis[s] = 0; vis[s] = true; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; for(int i = head[u]; i != -1;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]) { vis[v] = true; q.push(v); } } } } if(pre[t] == -1)return false; else return true;}//返回的是最大流,cost存的是最小费用int minCostMaxflow(int s,int t,double &cost) { int flow = 0; cost = 0; while(spfa(s,t)) { int Min = INF; for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) { if(Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow; } for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) { edge[i].flow += Min; edge[i^1].flow -= Min; cost += edge[i].cost * Min; } flow += Min; } return flow;}int n, m, x, y, t, cap;double cost, ans;int main() { freopen("input.txt","r",stdin); scanf("%d", &T); while (T--) { scanf("%d %d", &n, &m); init(n+2); for (int i = 1; i <= n; i++) { scanf("%d %d", &x, &y); t = min(x, y); x -= t, y -= t; if (x) addedge(0, i, x, 0); if (y) addedge(i, n+1, y, 0); } for (int i = 1; i <= m; i++) { scanf("%d %d %d %lf", &x, &y, &cap, &cost); if (cap > 0) addedge(x, y, 1, 0); if (cap-1 > 0) addedge(x, y, cap-1, -log(1.0-cost)); } ans = 0; minCostMaxflow(0, n+1, ans); printf("%.2lf\n", 1.0-exp(-ans)); }}
阅读全文
0 0
- Coding Contest
- hdu5988 Coding Contest
- hdoj 5988 Coding Contest
- HDU5988-Coding Contest
- HDU-5988 Coding Contest
- hdu 5988 Coding Contest (费用流)
- HDU 5988 Coding Contest(费用流)
- 【HDU 5988】 Coding Contest 【费用流】
- HDU-5988-Coding Contest(费用流)
- Coding Contest-青岛区域赛网络流
- hdu 5988 Coding Contest (最小费用流)
- hdu 5988 Coding Contest (费用流变形)
- HDU-5988 Coding Contest 最大费用流
- hdu 5988 Coding Contest 费用流
- HDU 5988 Coding Contest(费用流)
- Helvetic Coding Contest 2016 C2. Brain Network (medium)
- codeforces Helvetic Coding Contest 2016 D2 The Wall (medium)
- HDU 5988 Coding Contest(最小费用最大流)
- hibernate-初体验
- 【iOS】仿知乎日报,RxSwift-Part1-首页搭建
- ejabberd数据库本地化
- Linux进程间通信(一)之无名管道(PIPE)和有名管道(FIFO)
- HTML入门7
- Coding Contest
- 【iOS】仿知乎日报,RxSwift-Part2-详情页的搭建
- Eclipse和Myeclipse优化之Preferences
- 递归的基本原则
- Matrix Sum
- 关于HTTP协议
- 六级_第九天
- K3 WISE 12.3 中间层在虚拟机中注册
- Java方法中返回值,和打印的理解