zoukankan      html  css  js  c++  java
  • hdu 3996 (最大权闭合图)

    题意:有n个区域布局,每个区域有一些金矿,挖开金矿需要一定的费用,可以得到一定的利润,要想挖开一个金矿,必须挖开所有在这个金矿上边的金矿,求最大利益,给的数据价值太大,用64位。

    分析:如果一个金矿可以获利,就从源点引一条边,容量为获得的利益,否则向汇点引一条边,容量为损耗,一个金矿向所有的必须在它之前开发的金矿连边,容量为无穷大。求出最大流就是最小损耗,,,







    #include<stdio.h>
    #include<string.h>
    const int N=2600;
    const __int64 inf=0x3fffffffffffffff;
    int dis[N],gap[N],head[N],num,start,end,ans;
    struct edge
    {
        int st,ed,next;
        __int64 flow;
    }e[N*100];
    void addedge(int x,int y,__int64 w)
    {
        e[num].st=x;e[num].ed=y;e[num].flow=w;e[num].next=head[x];head[x]=num++;
        e[num].st=y;e[num].ed=x;e[num].flow=0;e[num].next=head[y];head[y]=num++;
    }
    __int64 dfs(int u,__int64 minflow)
    {
        if(u==end)return minflow;
        int i,v,min_dis=ans-1;
        __int64 f,flow=0;
        for(i=head[u];i!=-1;i=e[i].next)
        {
            if(e[i].flow<=0)continue;
            v=e[i].ed;
            if(dis[v]+1==dis[u])
            {
                f=dfs(v,e[i].flow>minflow-flow?minflow-flow:e[i].flow);
                e[i].flow-=f;
                e[i^1].flow+=f;
                flow+=f;
                if(flow==minflow)break;
                if(dis[start]>=ans)return flow;
            }
            min_dis=min_dis>dis[v]?dis[v]:min_dis;
        }
        if(flow==0)
        {
            if(--gap[dis[u]]==0)
                dis[start]=ans;
            dis[u]=min_dis+1;
            gap[dis[u]]++;
        }
        return flow;
    }
    __int64 isap()
    {
        __int64 maxflow=0;
        memset(dis,0,sizeof(head));
        memset(gap,0,sizeof(gap));
        gap[0]=ans;
        while(dis[start]<ans)
            maxflow+=dfs(start,inf);
        return maxflow;
    }
    int main()
    {
        int i,j,n,m,t,x,y,w,op=1;
        __int64 sum;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            memset(head,-1,sizeof(head));
            num=0;start=0;end=n*25+1;sum=0;ans=end+1;
            for(i=0;i<n;i++)
            {
                scanf("%d",&m);
                for(j=1;j<=m;j++)
                {
                    scanf("%d%d%d",&x,&y,&w);
                    if(y-x>=0)
                    {
                        addedge(start,i*25+j,y-x);
                        sum+=y-x;
                    }
                    else addedge(i*25+j,end,x-y);
                    while(w--)
                    {
                        scanf("%d%d",&x,&y);
                        addedge(i*25+j,(x-1)*25+y,inf);
                    }
                }
            }
            printf("Case #%d: %I64d
    ",op++,sum-isap());
        }
        return 0;
    }







  • 相关阅读:
    plt.annotate() 在图中标注文字
    numpy 的 ravel() 和 flatten() 扁平化函数
    springboot 国际化
    springboot 日志
    springboot render 和 重定向
    将jar包 引入到maven
    requests 上传图片加额外参数
    java 占位符
    springboot JSR303 后端数据校验
    Python入门学习笔记10:函数式编程:匿名函数、高阶函数、装饰器
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3268576.html
Copyright © 2011-2022 走看看