UVALive - 7740 Coding Contest 2016 青岛区域赛 (费用流)
题意:每个点i有\(s_i\)个人和\(b_i\)份食物,每个人都要找到一份食物.现在有M条有向边,从点i到点j,容量为c,第一次走过不要紧,从第二次开始就要承担\(p(0<p<1)\)的道路损坏的风险.题目保证每个人都能拿到食物,求这个风险的最小值.
分析:建立源点S和汇点T.从S到点i建容量为\(s_i\),费用为0的边;从点i到T建容量为\(b_i\),费用为0的边.
风险的最小值可以转化为求安全达成目标的. 则\(ans = \prod (1-p_i)^{k_i}\),
对ans取对数,\(log(ans) = \sum k_i*log(1-p_i)\).因为需要求这个值最大,所以费用需要取反.
因为第一次走没有风险,可以将这条容量为1的边分离出来,若容量还有剩余则建容量为\(c-1\),费用为\(-log(1-p)\)的边.
跑一遍费用流,费用取反再还原之后就是最大的安全通过的概率,1减去这个概率就是最小的风险.
#include<bits/stdc++.h>
using namespace std;
#define eps 1e-7
const int MAXN = 10005;
const int MAXM = 100005;
const int INF = 0x3f3f3f3f;
struct Edge{
    int to, next, cap, flow;
    double cost;
} edge[MAXM];
int head[MAXN], tot;
int pre[MAXN];
double dis[MAXN];
bool vis[MAXN];
int N;
void init(int n)
{
    N = n;
    tot = 0;
    memset(head, -1, sizeof(head));
}
void AddEdge(int u, int v, int cap, double cost)
{
    edge[tot] = (Edge){v,head[u],cap,0,cost};
    head[u] = tot++;
    edge[tot] = (Edge){u,head[v],0,0,-cost};
    head[v] = tot++;
}
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;
}
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 have[MAXN];
int need[MAXN];
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    #endif
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d %d",&n,&m);
        init(n+2);
        int u,v; double w;
        int s= 0, t = n+1;
        for(int i=1 ; i<=n; ++i){
            scanf("%d %d", &need[i], &have[i]);
        }
        for(int i=1;i<=n;++i){
            AddEdge(s,i,need[i],0);
            AddEdge(i,t,have[i],0);
        }
        int c;
        double p;
        for(int i=1;i<=m;++i){
            scanf("%d %d %d %lf",&u, &v, &c, &p);
            if(c >= 1) AddEdge(u,v,1,0.0);
            if(c > 1) AddEdge(u,v,c-1,-log2(1.0-p));
        }
        double cost = 0.0;
        minCostMaxflow(s,t,cost);
        //cout<<cost<<endl;
        printf("%.2f\n",1.0-pow(2.0,-cost));
    }
    return 0;
}
UVALive - 7740 Coding Contest 2016 青岛区域赛 (费用流)的更多相关文章
- 2016青岛区域赛.Coding Contest(费用流 + 概率计算转换为加法计算)
		Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ... 
- HDU 5880 Family View (2016 青岛网络赛 C题,AC自动机)
		题目链接 2016 青岛网络赛 Problem C 题意 给出一些敏感词,和一篇文章.现在要屏蔽这篇文章中所有出现过的敏感词,屏蔽掉的用$'*'$表示. 建立$AC$自动机,查询的时候沿着$fa ... 
- ACM-ICPC 2016亚洲区域赛(沈阳站)游记(滚粗记)
		首发于QQ空间和知乎,我在这里也更一下. 前言 以前高中搞竞赛的时候,经常看到神犇出去比赛或者训练之后写游记什么的,感觉萌萌哒.但是由于太弱,就没什么心情好写.现在虽然还是很弱,但是抱着享受的心情 ... 
- ACM/ICPC2016 青岛区域赛
		A(hdu5982).(模拟) 题意:输入n对数,将每对数相乘并相加 分析:模拟 B(hdu5983).(模拟) 题意:给你一个二阶魔方,问能否通过一次旋转使得给定魔方的每个面颜色相同 分析:模拟 C ... 
- 2019.6.1 模拟赛——[ 费用流 ][ 数位DP ][ 计算几何 ]
		第一题:http://codeforces.com/contest/1061/problem/E 把点集分成不相交的,然后跑费用流即可.然而错了一个点. #include<cstdio> ... 
- 2016 年 ACM/ICPC 青岛区域赛 Problem C Pocky
		昨晚乱入学弟的训练赛,想了一下这个题.推导的过程中,加深了对公理化的概率论理解.$\newcommand{\d}{\mathop{}\!\mathrm{d}}$ 解法一 考虑 $ d < L$ ... 
- The 2014 ACM-ICPC Asia Mudanjiang Regional Contest(2014牡丹江区域赛)
		The 2014 ACM-ICPC Asia Mudanjiang Regional Contest 题目链接 没去现场.做的网络同步赛.感觉还能够,搞了6题 A:这是签到题,对于A堆除掉.假设没剩余 ... 
- 2016ACM青岛区域赛题解
		A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ... 
- HDU - 5878 2016青岛网络赛 I Count Two Three(打表+二分)
		I Count Two Three 31.1% 1000ms 32768K I will show you the most popular board game in the Shanghai ... 
随机推荐
- linux通过shell脚本修改文件内容
			sed -i 's/abc/xxx/g' file abc修改前的字符串xxx是修改后的字符串file是要被修改的文件 
- NestedScrollView,RecyclerView
			为什么把它们放一起呢, 是因为它有着相同的特点 在新版的support-v4兼容包里面有一个NestedScrollView控件,这个控件其实和普通的ScrollView并没有多大的区别,这个控件其实 ... 
- axios如何进行跨域以及对返回格式为回调函数字符串的处理
			自从vue2.0开始不对vue-resouce进行维护了,转而用axios进行代替,axios的官方文档写的很详细,附上链接一枚:http://www.jianshu.com/p/df464b26ae ... 
- Spring学习笔记--使用注解装配
			使用@Autowired注解 从Spring2.5开始,最有趣的一种装配Spring Bean的方式是使用注解自动装配Bean的属性.Spring默认禁用注解装配,最简单的启用方式是使用Spring的 ... 
- My97DatePicker设置,包括隐藏 清空,设置最大日期等   转载
			My97DatePicker是一款非常灵活好用的日期控件.使用非常简单. 1.下载My97DatePicker组件包 2.在页面中引入该组件js文件: <script type=&quo ... 
- win10怎么关闭把管理员权限
			按住WIN+R 计算机配置----Windows设置----安全设置----本地策略----安全选项----用户账户控制:以管理员批准模式运行所有管理员,把启用改为禁止然后重启电脑 
- layerui如何设置显示的位置?
			转自:http://www.layui.com/doc/modules/layer.html#offset layer.open({ type: 1,//默认:0 (0表示信息框,1表示页面层,2表示 ... 
- jQuery设置内容和属性方
			何问起 hovertree.com 设置内容 - text().html() 以及 val()text() - 设置或返回所选元素的文本内容html() - 设置或返回所选元素的内容(包括 HTML ... 
- CSS文本对齐text-align详解
			1.语法 text-align具体参数如下: 语法:text-align : left | right | center | justify 说明:设定元素内文本的水平对齐方式. 参数:left : ... 
- spring could Windows打包构建docker镜像到linux
			工程模拟参考:http://blog.csdn.net/forezp/article/details/70198649 一.工程结构 二.Pom配置 <build> <plugins ... 
