http://acm.split.hdu.edu.cn/showproblem.php?pid=5988

题意:
在acm比赛的时候有多个桌子,桌子与桌子之间都有线路相连,每个桌子上会有一些人和一些食物,现在要吃午饭了,有些人就可能需要到别的桌子去拿食物,但是必须沿着线路走,每根线路第一个人走时没事,接下来的人走时会有一定概率使网络瘫痪,并且每根线路最多可以走c人。现在问使网络瘫痪的最低概率是多少?

思路:
建立费用流,由于概率是要相乘,这里可以转换成log后进行计算,最后再转换回来即可。

由于这题是浮点数,所以在松弛的时候需要加eps,否则会TLE。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = +;
const double eps = 1e-; int n,m; struct Edge
{
int from, to, cap, flow;
double cost;
Edge(int u, int v, int c, int f, double w) :from(u), to(v), cap(c), flow(f), cost(w) {}
}; struct MCMF
{
int n, m;
vector<Edge> edges;
vector<int> G[maxn];
int inq[maxn];
double d[maxn];
int p[maxn];
int a[maxn]; void init(int n)
{
this->n = n;
for (int i = ; i<n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap, double cost)
{
edges.push_back(Edge(from, to, cap, , cost));
edges.push_back(Edge(to, from, , , -cost));
m = edges.size();
G[from].push_back(m - );
G[to].push_back(m - );
} bool BellmanFord(int s, int t, int &flow, double & cost)
{
for (int i = ; i<n; i++) d[i] = INF;
memset(inq, , sizeof(inq));
d[s] = ; inq[s] = ; p[s] = ; a[s] = INF; queue<int> Q;
Q.push(s);
while (!Q.empty()){
int u = Q.front(); Q.pop();
inq[u] = ;
for (int i = ; i<G[u].size(); i++){
Edge& e = edges[G[u][i]];
if (e.cap>e.flow && d[e.to]>d[u] + e.cost +eps){
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] = ; }
}
}
} if (d[t] == INF) return false;
flow += a[t];
cost += d[t] * a[t];
for (int u = t; u != s; u = edges[p[u]].from)
{
edges[p[u]].flow += a[t];
edges[p[u] ^ ].flow -= a[t];
}
return true;
} double MincostMaxdflow(int s, int t){
int flow = ;
double cost = ;
while (BellmanFord(s, t, flow, cost));
return cost;
}
}t; int a[maxn],b[maxn],c[maxn]; int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
int src=,dst=*n+;
t.init(dst+);
for(int i=;i<n;i++)
{
scanf("%d%d",&a[i],&b[i]);
c[i]=a[i]-b[i];
if(c[i]<) t.AddEdge(i+,dst,-c[i],);
else if(c[i]>) t.AddEdge(src,i+,c[i],);
}
for(int i=;i<m;i++)
{
int u,v,c; double p;
scanf("%d%d%d%lf",&u,&v,&c,&p);
p=-log(-p);
if(c==) continue;
if(c==) t.AddEdge(u,v,,);
else if(c>)
{
t.AddEdge(u,v,,);
t.AddEdge(u,v,c-,p);
}
}
double ans = t.MincostMaxdflow(src,dst);
ans=exp(-ans);
printf("%.2f\n",-ans);
}
return ;
}

最新文章

  1. Matlab 绘制三维立体图(以地质异常体为例)
  2. dynamic 用法
  3. 2-python学习——hello world
  4. sruts2 自定义类型转换器
  5. [terry笔记]Oracle10g/11g安装-redhat5.5
  6. *gravity的取值详表
  7. ehcache集群的配置
  8. Poj3680 Intervals
  9. Netty+Tomcat热部署端口占用解决办法(转)
  10. 大数据全栈式开发语言 – Python
  11. PHP中递归最详解释.
  12. NNSZ OIers&#39; Blog Archive
  13. struts快速入门第一篇 —— struts相关XML配置映射及讲解
  14. Java内存模型之重排序
  15. Tomcat的startup.bat启动后显示乱码
  16. opencv关于Mat类中的Scalar()---颜色赋值
  17. [Android] Android 使用 Greendao 操作 db sqlite(2)-- 封装DaoUtils类
  18. 第二章 JavaScript总结(下)
  19. Beta 冲刺报告模板
  20. jquery stop()、callback、鏈接

热门文章

  1. Hive静态分区和动态分区
  2. 转:&quot;为自动填充列调整大小期间不能执行此操作&quot;解决办法 .
  3. docker Dockerfile指令ADD和COPY的区别,添加目录方法
  4. GUI界面修饰
  5. [转载]表单校验之datatype
  6. Linux 进程管理 ps、top、pstree命令
  7. 关于reduce输出write方法
  8. 监控nginx服务
  9. HTML(续)
  10. 使用准现网的数据,使用本地的样式脚本,本地调试准现网页面(PC适用)