• HDU 4971 A simple brute force problem.(最大权闭合图)


    题意:n个项目m个问题,完成每个项目有对应收入,解决每个问题需要对应花费,

            给出每个项目需解决的问题以及各问题间的依赖关系,求最大利润(可完成部分或全部项目);

    思路:网络流中的最大权闭合图的典型应用——利润问题,参考07年day2国家集训队胡伯涛的论文;

            参考:http://blog.csdn.net/u012965890/article/details/38761043

            闭合图指所有顶点的出边指向的所有顶点均在图中;

            最大权闭合图:点权和最大的闭合图,即权值最大的子闭合图;

            建图思路:

           工程为点权为正的点,问题为点权为负的点;

            源点到工程建边,容量为工程对应的利润;

            问题到汇点建边,容量为问题花费;

           工程到问题建边,容量为正无穷;

           问题间建边,容量为正无穷,不用判环;

        最终所求利润为工程总利润-最大流;

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define inf 0x7fffffff
    int n,m,st,ed;
    int p[500100],q[500100];
    int dis[500010],vis[500010];
    int head[500010];
    int cnt,u,v;
    struct node
    {
        int v,c,next;
    };
    node E[5000100];
    void add(int u,int v,int w) //建边
    {
        E[cnt].v=v;
        E[cnt].c=w;
        E[cnt].next=head[u];
    
        head[u]=cnt++;
        E[cnt].v=u;
        E[cnt].c=0;
        E[cnt].next=head[v];
        head[v]=cnt++;
    }
    bool bfs()
    {
        memset(dis,0,sizeof(dis));
        dis[st]=1;
        queue<int>Q;
        Q.push(st);
        while(!Q.empty())
        {
            int d=Q.front();
            Q.pop();
            for(int i=head[d];i!=-1;i=E[i].next)
            {
                if(E[i].c&&!dis[E[i].v])
                {
                    dis[E[i].v]=dis[d]+1;
                    Q.push(E[i].v);
                }
            }
        }
        return dis[ed]>0;
    }
    int dicnic(int low,int p)  //增广
    {
        int f=low;
        if(p==ed) return f;
        for(int i=head[p];i!=-1;i=E[i].next)
        {
            if(E[i].c&&dis[E[i].v]==dis[p]+1)
            {
                int a=E[i].c;
                int t=dicnic(min(a,low),E[i].v);
                E[i].c-=t;
                E[i^1].c+=t;
                low-=t;
                if(low<=0) break;
            }
        }
        //printf("fjashdfj
    ");
        if(f-low<=0) dis[p]=-1;
        return f-low;
    }
    int flow()
    {
        int sum=0;
        while(bfs())
            sum+=dicnic(inf,st);//参数位置不能改变
        return sum;
    }
    int main()
    {
        int t,cas,i,j,k,temp;
        scanf("%d",&t);
        for(cas=1;cas<=t;cas++)
        {
            scanf("%d%d",&n,&m);
            int sr=0,sc=0;
            st=0,ed=n+m+1;  //设置源点,汇点
            cnt=0;
            memset(head,-1,sizeof(head));
            for(i=1;i<=n;i++)
            {
                scanf("%d",&p[i]);
                add(st,i,p[i]);  //源点到项目建边
                sr+=p[i];        //总利润
            }
            for(i=1;i<=m;i++)
            {
                scanf("%d",&q[i]); 
                add(i+n,ed,q[i]); //问题到汇点建边
            }
            for(i=1;i<=n;i++)
            {
                scanf("%d",&k);
                while(k--)
                {
                    scanf("%d",&temp);temp++;
                    add(i,temp+n,inf); //项目到问题建边
                }
            }
            for(i=1;i<=m;i++)
                for(j=1;j<=m;j++)
                {
                    scanf("%d",&temp);
                    if(temp==1)
                    add(i+n,j+n,inf); //问题建边,容量设为inf,可不用判环
                }
            int ans=sr-flow(); 
             printf("Case #%d: ",cas);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    VSCode编写 Vue 项目标签内显示写CSS提示设置
    Vue 炫酷 Echarts 图表
    vue 动态生成拓扑图
    Vue 全局 websocket
    Vue 自定义组件v-model父子组件传值双向绑定
    vue项目Echarts更新数据是数据表展示错版
    Vue图片加载错误、图片加载失败的处理
    Vue 使用 Ant-d 简单实现左侧菜单栏和面包屑功能
    Vue Echarts图表dataZoom缩放区域根据数据量显示
    Echarts图例数据太多实现滚动效果
  • 原文地址:https://www.cnblogs.com/dashuzhilin/p/4646398.html
Copyright © 2020-2023  润新知