zoukankan      html  css  js  c++  java
  • poj3308 最小割

     因为行可以了,那列就不行,所以根据行列建立最小割模型。

    然后这题精妙之处在于把乘法取对数后转化为加法,瞬间就简单了。

    保证精度,C++AC ,16MS G++WA。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<math.h>
    #define maxn 120
    #define INF 10000000
    using namespace std;
    struct node
    {
        int to;
        double v;
        int flag;
        int next;
    }edge[2000];
    int pre[maxn],index,vis[maxn],n,m,L,st,se;
    double col[55],row[55];
    double min(double x,double y)
    {
        return x<y?x:y;
    }
    void add(int x,int y,double z)
    {
        edge[index].to=y;
        edge[index].v=z;
        edge[index].flag=index+1;
        edge[index].next=pre[x];
        pre[x]=index++;
        edge[index].to=x;
        edge[index].v=0;
        edge[index].flag=index-1;
        edge[index].next=pre[y];
        pre[y]=index++;
    }
    double dfs(int u,double low)
    {
        int i;
        double used=0;
        if(u==se)return low;
        for(i=pre[u];i!=-1;i=edge[i].next)
        {
            if(vis[edge[i].to]==vis[u]+1&&edge[i].v>0)
            {
                double a=dfs(edge[i].to,min(low-used,edge[i].v));
                edge[i].v-=a;
                edge[edge[i].flag].v+=a;
                used+=a;
                if(used-low>1e-7)break;
            }
        }
        if(!used)vis[u]=-1;
        return used;
    }
    int BFS()
    {
        int i;
        queue<int>q;
        memset(vis,-1,sizeof(vis));
        vis[0]=0;
        q.push(0);
        while(!q.empty())
        {
            int t=q.front();
            q.pop();
            for(i=pre[t];i!=-1;i=edge[i].next)
            {
                if(vis[edge[i].to]<0&&edge[i].v>0)
                {
                    vis[edge[i].to]=vis[t]+1;
                    q.push(edge[i].to);
                }
            }
        }
        return vis[se]!=-1;
    }
    void init()
    {
        int i;
        index=1;
        st=0,se=115;
        memset(pre,-1,sizeof(pre));
        scanf("%d%d%d",&n,&m,&L);
        for(i=1;i<=n;i++)
        {
            scanf("%lf",&row[i]);
            add(st,i,log(row[i]));
        }
        for(i=1;i<=m;i++)
        {
            scanf("%lf",&col[i]);
            add(i+50,se,log(col[i]));
        }
        for(i=0;i<L;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,50+y,INF*1.0);
        }
    }
    void slove()
    {
        double ans=0;
        while(BFS())
        {
            while(1)
            {
                double a=dfs(0,INF*1.0);
                if(a<1e-7)break;
                ans+=a;
            }
        }
        printf("%.4lf
    ",exp(ans));
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            init();
            slove();
        }
    }
  • 相关阅读:
    【转】java线程池ThreadPoolExecutor使用介绍
    java的类加载机制
    java面试问题分类
    ConcurrentHashMap总结
    ffmpeg对视频封装和分离
    SSM的整合
    单例模式的七种写法
    SecureCRT的快捷键
    linux下mysql常用命令
    maven操作
  • 原文地址:https://www.cnblogs.com/sweat123/p/4870321.html
Copyright © 2011-2022 走看看