Coding Contest

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

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
 
 
 
题意:有n个区域,每个区域有一些人数si和食物bi,区域之间有m条定向路径,每条路径有人数通过上限ci。路径之间铺了电线,每当有人通过路径时有pi的概率会触碰到电线,但是第一个通过的人一定不会触碰到电线。求每个人都通过路径获取到食物后触碰到电线的最小概率。
思路:首先每个区域的一些人都直接获取自己区域的食物,如果人过量,源点链接本区域,容量是过量的人数,费用是0;如果食物过量,本区域连接汇点,容量是过量的食物,费用是0。剩下的人通过路径到其他区域获取食物,m条路径之间建立边,首先是一定不会触碰,容量是1,花费为0,;接下来的才是容量为ci-1的边,并且还拥有一个费用,这就是一个最小费用最大流的问题,但是这个费用怎么转换呢?把每个概率取log(1-pi),并且取负数-log(1-pi)。这样的话最小花费(-log(x1))+(-log(x2))+(-log(x3))+....=-(log(x1)+log(x2)+log(x3)+...)=-log(x1*x2*x3...)。最后最小费用ans取负数再作为e的指数,即exp(-ans)是最大乘积。
 
代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<double,int> P;
#define PI acos(-1.0)
const int maxn=,maxm=1e5+,inf=0x3f3f3f3f,mod=1e9+;
const ll INF=1e18+;
const double eps=0.000001;
struct edge
{
int from,to;
int cap;
double cost;
int rev;
};
int NN;
vector<edge>G[maxn];
double h[maxn];
///顶点的势,取h(u)=(s到u的最短距离),边e=(u,v)的长度变成d`(e)=d(e)+h(u)-h(v)>=0
double dist[maxn];
int prevv[maxn],preve[maxn];///前驱结点和对应的边
void addedge(int u,int v,int cap,double cost)
{
edge e;
e.from=u,e.to=v,e.cap=cap,e.cost=cost,e.rev=G[v].size();
G[u].push_back(e);
e.from=v,e.to=u,e.cap=,e.cost=-cost,e.rev=G[u].size()-;
G[v].push_back(e);
}
double min_cost_flow(int s,int t,int f)
{
double res=0.0;
fill(h,h+NN,0.0);
while(f>)
{
priority_queue<P,vector<P>,greater<P> >q;
fill(dist,dist+NN,inf);
dist[s]=0.0;
q.push(P(dist[s],s));
while(!q.empty())
{
P p=q.top();
q.pop();
int u=p.second;
if(dist[u]<p.first) continue;
for(int i=; i<G[u].size(); i++)
{
edge e=G[u][i];
if(e.cap>&&dist[e.to]-(dist[u]+e.cost+h[u]-h[e.to])>=eps)
{
dist[e.to]=dist[u]+e.cost+h[u]-h[e.to];
prevv[e.to]=u;
preve[e.to]=i;
q.push(P(dist[e.to],e.to));
}
}
}
if(fabs(dist[t]-inf)<=eps) return res;
for(int i=; i<NN; i++) h[i]+=dist[i];
int d=f;
for(int i=t; i!=s; i=prevv[i])
d=min(d,G[prevv[i]][preve[i]].cap);
f-=d;
res+=d*h[t];
//cout<<d<<" "<<h[t]<<" "<<d*h[t]<<endl;
for(int i=t; i!=s; i=prevv[i])
{
//cout<<i<<" ";
edge &e=G[prevv[i]][preve[i]];
e.cap-=d;
G[i][e.rev].cap+=d;
}
//cout<<s<<endl;
}
return res;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
int s=,t=n+,f;
NN=t+;
for(int i=; i<=n; i++)
{
int a,b;
scanf("%d%d",&a,&b);
int x=min(a,b);
a-=x,b-=x;
if(a>) addedge(s,i,a,);
else if(b>) addedge(i,t,b,);
}
for(int i=; i<=m; i++)
{
int u,v,cap;
double cost;
scanf("%d%d%d%lf",&u,&v,&cap,&cost);
if(cap>) addedge(u,v,,);
if(cap->) addedge(u,v,cap-,-*log(1.0-cost));
}
double sum=min_cost_flow(s,t,inf);
printf("%.2f\n",1.0-exp(-1.0*sum));
for(int i=; i<NN; i++) G[i].clear();
}
return ;
}

最小费用最大流

HDU 5988.Coding Contest 最小费用最大流的更多相关文章

  1. HDU 5988 Coding Contest(最小费用最大流变形)

    Problem DescriptionA coding contest will be held in this university, in a huge playground. The whole ...

  2. HDU5988/nowcoder 207G - Coding Contest - [最小费用最大流]

    题目链接:https://www.nowcoder.com/acm/contest/207/G 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 ...

  3. hdu 1533 Going Home 最小费用最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533 On a grid map there are n little men and n house ...

  4. hdu 3667(拆边+最小费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3667 思路:由于花费的计算方法是a*x*x,因此必须拆边,使得最小费用流模板可用,即变成a*x的形式. ...

  5. hdu 3488(KM算法||最小费用最大流)

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  6. hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))

    Special Fish Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  7. hdu 1533 Going Home 最小费用最大流 入门题

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  8. POJ 2195 & HDU 1533 Going Home(最小费用最大流)

    这就是一道最小费用最大流问题 最大流就体现到每一个'm'都能找到一个'H',但是要在这个基础上面加一个费用,按照题意费用就是(横坐标之差的绝对值加上纵坐标之差的绝对值) 然后最小费用最大流模板就是再用 ...

  9. HDU 5988 Coding Contest 最小费用流 cost->double

    Problem Description A coding contest will be held in this university, in a huge playground. The whol ...

随机推荐

  1. JAVA语言 第五周

    我准备在下一周对Java语法进行总结,现在写代码模板还要参考,语法掌握的不熟悉. 这一周除了对代码进行完善外,观看了一些java入门学习视频.

  2. HTML5将<video>视频设置为页面动态背景

    <!DOCTYPE html><html><head> <title>Operation Aborted Example</title> & ...

  3. sse实例

    一.前台 <script>//D:\wamp\www\node\xiangmuer\views\main // var source = new EventSource('http://1 ...

  4. 2018面向对象程序设计(Java) 第2周学习指导及要求

    2018面向对象程序设计(Java) 第2周学习指导及要求(2018.9.3-2018.9.9)   学习目标 适应老师教学方式,能按照自主学习要求完成本周理论知识学习: 掌握Java Applica ...

  5. 带轮播图、导航栏、商品的简单html,以及轮播图下边数字随轮播图的改变而改变

    ---恢复内容开始--- 在做这个的时候,最不会的是中间轮播图下边的数字是如何实现转变的,后来加入了jQuery就能实现了. css部分: <style type="text/css& ...

  6. python-ceilometerclient命令行(1)

    1.导入模块,可以动态获取模块中方法并调用,其功能与from...import...一致 2. callback = getattr(actions_module, attr) 从模块中获取方法. 调 ...

  7. 如何使用eclipse创建JAVA项目并写一个简单的HelloWorld

    输入项目名称  点击完成(Finish) 原文地址:https://blog.csdn.net/qq_36798713/article/details/79530056

  8. VS2015 添加web服务(电子看板)

    鼠标右键点击项目,选择引用----添加服务引用,输入WS地址后单击转到 http://ERPPRD02:8000/sap/bc/srt/wsdl/flv_10002A111AD1/bndg_url/s ...

  9. xshell 5 书写汉字乱码

    使用win10安装xshell5后发现使用xshell连接虚拟机后,能识别中文但是无法输入中文了   控制面板--语言   删除除中文输入法之外的所有输入法和美式键盘 然后就可以正常输入中文了,为了英 ...

  10. vue-router导航守卫,限制页面访问权限

    在项目开发过程中,经常会需要登录.注册.忘记密码等,也有很多页面是需要登录后才能访问,有些页面是无需登录就可以访问的,那么vue是怎么来限制这些访问权限问题的呢? vue-router导航守卫的bef ...