• HDU 5988 Coding Contest(费用流+浮点数)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988

    题目大意:

    给定n个点,m条有向边,每个点是一个吃饭的地方,每个人一盒饭。每个点有S个人,有B盒饭。每条边只能被走c次,每条边上都有电线,
    第一个人通过的时候,不会破坏电线,从第二个人开始,每次都有概率p破坏掉电线。使得每个人都能吃饭,求最小破坏电线的概率。

    解题思路:

    题目要求我们求最小破坏电线的概率,就是一个最小乘积问题,加上log可以将其转变为加法,那样就可以使用费用刘来解决了。

    按以下方式建图:

    ①源点st向第i个人建边,流量为S。

    ②第i个人向汇点建边,流量为B。

    ③u->v连边,流量为c,花费为-log(1-p)。

    然后跑费用流,1-exp(-cost)即为答案。

    代码

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<vector>
      8 #define LL long long
      9 #define pii pair<double,int>
     10 #define pll pair<long long,long long>
     11 #define rep(i,a,b) for(int i=a;i<=b;i++)
     12 #define per(i,a,b) for(int i=a;i>=b;i--)
     13 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
     14 #define bug cout<<"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"<<endl;
     15 #define bugc(_) cout << (#_) << " = " << (_) << endl;
     16 using namespace std;
     17 const double eps=1e-8;
     18 const int N=1e2+5;
     19 const int M=1e5+5;
     20 const int INF=0x3f3f3f3f;
     21 
     22 struct node{
     23     int to,next,flow;
     24     double cost;
     25 }edge[M*2]; 
     26 
     27 int cnt,st,en,n,m;
     28 int head[N],pre[N];
     29 double dis[N];//dis[i]表示到dis[i]为止不破坏电线的最大概率
     30 bool vis[N];
     31 
     32 int sgn(double x) { return x < -eps? -1: x > eps; }
     33 
     34 void init(){
     35     cnt=2;
     36     memset(head,0,sizeof(head));
     37 } 
     38 
     39 void link(int u,int v,int flow,double cost){
     40     edge[cnt]=node{v,head[u],flow,cost};
     41     head[u]=cnt++;
     42     edge[cnt]=node{u,head[v],0,-cost};
     43     head[v]=cnt++;
     44 }
     45 
     46 bool spfa() {
     47     memset(pre,0,sizeof(pre));
     48     memset(vis,false,sizeof(vis));
     49     for(int i=st;i<=en;i++) dis[i]=INF;
     50     dis[st]=0;
     51     queue<int>q;
     52     q.push(st);
     53     while(!q.empty()){
     54         int u=q.front();
     55         q.pop();
     56         vis[u]=false;
     57         for(int i=head[u];i;i=edge[i].next){
     58             node t=edge[i];
     59             if(t.flow&&dis[t.to]>dis[u]+t.cost+eps){
     60                 dis[t.to]=dis[u]+t.cost;
     61                 pre[t.to]=i;
     62                 if(!vis[t.to]){
     63                     vis[t.to]=true;
     64                     q.push(t.to);
     65                 }
     66             }
     67         }
     68     }
     69     if(dis[en]==INF)
     70         return false;
     71     return true;
     72 }
     73 
     74 void mcmf(int &flow,double &cost){
     75     while(spfa()){
     76         int mmin=INF;
     77         for(int i=pre[en];i;i=pre[edge[i^1].to]){
     78             mmin=min(mmin,edge[i].flow);
     79         }
     80         for(int i=pre[en];i;i=pre[edge[i^1].to]){
     81             edge[i].flow-=mmin;
     82             edge[i^1].flow+=mmin;
     83             cost+=edge[i].cost*mmin;
     84         }
     85         flow+=mmin;
     86     }
     87 }
     88 
     89 int main(){
     90     int T;
     91     scanf("%d",&T);
     92     while(T--){
     93         init();
     94         int n,m;
     95         scanf("%d%d",&n,&m);
     96         st=0,en=n+1;
     97         for(int i=1;i<=n;i++){
     98             int s,b;
     99             scanf("%d%d",&s,&b);
    100             if(s-b>0) link(st,i,s-b,0);
    101             if(s-b<0) link(i,en,b-s,0);
    102         }
    103         for(int i=1;i<=m;i++){
    104             int u,v,flow;
    105             double p;
    106             scanf("%d%d%d%lf",&u,&v,&flow,&p);
    107             p=-log(1-p);
    108             if(flow>0) link(u,v,1,0);
    109             if(flow>1) link(u,v,flow-1,p);
    110         }
    111         int flow=0;
    112         double cost=0;
    113         mcmf(flow,cost);
    114         cost=exp(-cost);
    115         printf("%.2f
    ",1-cost);
    116     }
    117     return 0;
    118 }
  • 相关阅读:
    Linux下静态库与动态库
    通过js操作样式(评分)
    javascript学习
    2017年6月1日学习
    javascript学习2
    javascript学习:闭包和prototype原型使用基础
    关于“System.Data.ProviderIncompatibleException”类型的异常
    Android性能优化之ViewStub
    Activity Threa创建Window和View分析
    软键盘触发后弹起底部布局文件方法
  • 原文地址:https://www.cnblogs.com/fu3638/p/9897550.html
Copyright © 2020-2023  润新知