• poj3308Paratroopers(dinic)


    http://poj.org/problem?id=3308

    给两个定义

    最小割:对于图中的两个点(一般为源点和汇点)来说,如果把图中的一些边去掉,如果它们之间无法连通的话,则这些边组成的集合就叫为割了。如果这些边有权值,最小割就是指权值之和最小的一个割。

    最大流最小割:应用于网络中,指总流量不超过链路可承载的最大值,且在每条子路径上取尽可能少的流量。对任意一个只有一个源点一个汇点的图来说,从源点到汇点的最大流等于最小割。

    之前做二分图的时候看过一篇文章 现在依旧看这篇http://ip96cns.blog.163.com/blog/static/170095192201117465473/

    设置超级源点及超级汇点 行和列看做结点 每一个点看做一个边 把行和列两个结点连起来

    这个题是求最小乘积 刚开始还以为样例答案错了呢 用一个log函数就可以转换为相加

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<cmath>
      7 #include<queue>
      8 #define N 2510
      9 #define M 400100
     10 #define INF 0x3f3f3f3f
     11 #define eps 1e-8
     12 using namespace std;
     13 struct node
     14 {
     15     int u,v,next;
     16     double w;
     17 }edge[M];
     18 int head[N],t,vis[N],pp[N],dis[N];
     19 void init()
     20 {
     21     t=0;
     22     memset(head,-1,sizeof(head));
     23 }
     24 void add(int u,int v,double w)
     25 {
     26     edge[t].u = u;
     27     edge[t].v = v;
     28     edge[t].w = w;
     29     edge[t].next = head[u];
     30     head[u] = t++;
     31     edge[t].u = v;
     32     edge[t].v = u;
     33     edge[t].w = 0;
     34     edge[t].next = head[v];
     35     head[v] = t++;
     36 }
     37 int bfs(int e)
     38 {
     39     int i,u;
     40     double w;
     41     memset(dis,-1,sizeof(dis));
     42     queue<int>q;
     43     q.push(0);
     44     dis[0]=  0;
     45     while(!q.empty())
     46     {
     47         u = q.front();
     48         q.pop();
     49         for(i = head[u] ; i != -1 ; i = edge[i].next)
     50         {
     51             int v = edge[i].v;
     52             w = edge[i].w;
     53             if(w>eps&&dis[v]<0)
     54             {
     55                 dis[v] = dis[u]+1;
     56                 q.push(v);
     57             }
     58         }
     59     }
     60     if(dis[e]>0) return 1;
     61     return 0;
     62 }
     63 double dfs(int u,double te,int e)
     64 {
     65     int i;
     66     double s;
     67     if(u==e) return te;
     68     for(i = head[u] ; i != -1 ; i = edge[i].next)
     69     {
     70         int v = edge[i].v;
     71         double w = edge[i].w;
     72         if(w>eps&&dis[v]==dis[u]+1&&(s=dfs(v,min(te,w),e)))
     73         {
     74             edge[i].w-=s;
     75             edge[i^1].w+=s;
     76             return s;
     77         }
     78     }
     79     return 0;
     80 }
     81 int main()
     82 {
     83     int i,n,m,o,k,a,b;
     84     double p;
     85     cin>>o;
     86     while(o--)
     87     {
     88         cin>>n>>m>>k;
     89         init();
     90         for(i = 1; i <= n ; i++)
     91         {
     92             cin>>p;
     93             add(0,i,log(p));
     94         }
     95         for(i = 1; i <= m ; i++)
     96         {
     97             cin>>p;
     98             add(n+i,n+m+1,log(p));
     99         }
    100         for(i = 1 ; i <= k ; i++)
    101         {
    102             cin>>a>>b;
    103             add(a,n+b,INF);
    104         }
    105         double s = 0,ss=0;
    106         while(bfs(n+m+1))
    107         {
    108             ss = dfs(0,INF,n+m+1);
    109             if(ss>eps)
    110             s+=ss;
    111             else break;
    112         }
    113 
    114         printf("%.4f
    ",exp(s));
    115     }
    116     return 0;
    117 }
    View Code
  • 相关阅读:
    [cf553C]Love Triangles
    Unix目录结构的来历
    debian学习笔记9, putty连接debian的字体乱码修改设置。
    【转】Dictionary排序
    debian学习笔记9, putty连接debian的字体乱码修改设置。
    【转】可以用圆形的钻头钻出方孔吗
    【转】Dictionary排序
    关于设置sftp 指定端口
    【转】可以用圆形的钻头钻出方孔吗
    Unix目录结构的来历
  • 原文地址:https://www.cnblogs.com/shangyu/p/3149161.html
Copyright © 2020-2023  润新知