• POJ 3308 Paratroopers


    POJ_3308

    这个题目有点像二分图最小点集覆盖问题,但由于边带权,所以不能直接用二分图最大匹配来做。

    参考了别人的想法之后,发现构图的时候原来还是要用的二分图的思想,将行、列分别看做一个集合,由于最后求费用乘积的最小值,所以先传化成log2形式的费用,源点与行之间的容量初始化为log2行费用,列与汇点之间的容量初始化log2列费用。之后对读入的伞兵位置对应的行和列之间连一条有向边,容量为INF

        最后只要求一下最小割就可以了,也就是最大网络流。

    #include<stdio.h>
    #include
    <string.h>
    #include
    <math.h>
    double cap[110][110],flow[110][110],a[110];
    int q[110],p[110];
    int main()
    {
    int i,j,k,n,m,l,T,t,u,v,front,rear;
    double f,temp;
    scanf(
    "%d",&T);
    while(T--)
    {
    scanf(
    "%d%d%d",&m,&n,&l);
    t
    =m+n+1;
    for(i=0;i<=t;i++)
    for(j=0;j<=t;j++)
    {
    cap[i][j]
    =0.0;
    flow[i][j]
    =0.0;
    }
    for(i=1;i<=m;i++)
    {
    scanf(
    "%lf",&temp);
    cap[
    0][i]=log2(temp);
    }
    for(i=m+1;i<t;i++)
    {
    scanf(
    "%lf",&temp);
    cap[i][t]
    =log2(temp);
    }
    for(i=0;i<l;i++)
    {
    scanf(
    "%d%d",&u,&v);
    cap[u][m
    +v]=1000000000.0;
    }
    f
    =0;
    while(1)
    {
    for(i=1;i<=t;i++)
    a[i]
    =0.0;
    a[
    0]=1000000000.0;
    front
    =rear=0;
    q[rear
    ++]=0;
    while(front<rear)
    {
    u
    =q[front++];
    for(v=0;v<=t;v++)
    if(a[v]<1e-8&&cap[u][v]>flow[u][v])
    {
    temp
    =cap[u][v]-flow[u][v];
    a[v]
    =a[u]<temp?a[u]:temp;
    p[v]
    =u;
    q[rear
    ++]=v;
    }
    }
    if(a[t]<1e-8)
    break;
    for(u=t;u!=0;u=p[u])
    {
    flow[p[u]][u]
    +=a[t];
    flow[u][p[u]]
    -=a[t];
    }
    f
    +=a[t];
    }
    printf(
    "%.4f\n",pow(2,f));
    }
    return 0;
    }
  • 相关阅读:
    redis该怎么用
    cookie和session的比较
    web常见攻击
    请大神指导从大日志文件中统计关键字次数的办法
    apache中 MaxClients 与MaxRequestsPerChild
    如何提高缓存命中率
    CSU-ACM2018暑假集训比赛1
    CodeForces
    CodeForces
    CodeForces
  • 原文地址:https://www.cnblogs.com/staginner/p/2130001.html
Copyright © 2020-2023  润新知