• UVa 3487 & 蜜汁建图


    题意:

      有两家公司都想向政府申请某些资源的使用权,并且他们都提供了一些申请列表,列表中含有申请费用和资源种类,同一家公司的申请列表之间不含有重复的资源。政府只可以完整地接受和拒绝谋一份申请列表,问政府的最大收益是多少。

    SOL:

      建图很糜啊...神一样的建图,虽然这种类型...怎么说呢...反正就是这种类型...都会去想到最小割但是建不来图...

      因为题目有点看不懂...感觉树上跟题目完全是两个题目...(今天完全没有状态...) 也没有什么打的心情...就贴一下别人的题解学习以下这样建图好了  

      如果两家公司的申请之间没有任何矛盾,那么最大的收益就是所有的申请费用之和。如果某些列表之间有矛盾,那么就需要用最小的代价使两家公 司的申请没有任何矛盾。将每一条申请视作一个点,增加源点s和汇点t,从s向甲公司的每一条申请连一条弧,容量为该申请的费用;从乙公司的每一条申请向t 连一条弧,容量为每条申请对应的费用;然后对于甲公司的每一条申请,向所有与它矛盾的申请(只可能是乙公司的申请)连一条弧,容量为无穷大。那么,最小割 便是这个最小代价,用申请费用总和减去最小代价便是最大收益。

    然后贴个别人的代码(真是有脸啊...)    来自http://www.cnblogs.com/20143605--pcx/p/5069829.html的题解与代码....

      Code:

      

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<string>
    # include<vector>
    # include<list>
    # include<set>
    # include<map>
    # include<queue>
    # include<cstring>
    # include<algorithm>
    using namespace std;
     
    # define LL long long
    # define REP(i,s,n) for(int i=s;i<n;++i)
    # define CL(a,b) memset(a,b,sizeof(a))
    # define CLL(a,b,n) fill(a,a+n,b)
     
    const double inf=1e30;
    const int INF=1<<30;
    const int N=6005;
     
    /////////////////////////////////
    struct Edge
    {
        int fr,to,cap,fw;
        Edge(int _fr,int _to,int _cap,int _fw):fr(_fr),to(_to),cap(_cap),fw(_fw){}
    };
    struct Dinic{
        vector<Edge>edges;
        vector<int>G[N];
        int d[N],vis[N],cur[N];
        int s,t;
     
        void init(int n,int s,int t)
        {
            this->s=0,this->t=t;
            REP(i,0,n) G[i].clear();
            edges.size();
        }
     
        void addEdge(int u,int v,int cap)
        {
            edges.push_back(Edge(u,v,cap,0));
            edges.push_back(Edge(v,u,0,0));
            int len=edges.size();
            G[u].push_back(len-2);
            G[v].push_back(len-1);
        }
     
        bool BFS()
        {
            CL(vis,0);
            d[s]=0;
            vis[s]=1;
            queue<int>q;
            q.push(s);
            while(!q.empty()){
                int x=q.front();
                q.pop();
                REP(i,0,G[x].size()){
                    Edge &e=edges[G[x][i]];
                    if(!vis[e.to]&&e.cap>e.fw){
                        d[e.to]=d[x]+1;
                        vis[e.to]=1;
                        q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
     
        int DFS(int x,int a)
        {
            if(x==t||a==0) return a;
            int flow=0,f;
            for(int &i=cur[x];i<G[x].size();++i){
                Edge &e=edges[G[x][i]];
                if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.cap-e.fw)))>0){
                    e.fw+=f;
                    edges[G[x][i]^1].fw-=f;
                    flow+=f;
                    a-=f;
                    if(a==0) break;
                }
            }
            return flow;
        }
     
        int MaxFlow()
        {
            int flow=0;
            while(BFS()){
                CL(cur,0);
                flow+=DFS(s,INF);
            }
            return flow;
        }
    };
    Dinic dinic;
    ////////////////////////////////////
     
    int sum,maxn;
    int a[300005],b[300005];
    bool vis[3005][3005];
    int p1[3005],p2[3005];
     
    void init()
    {
        maxn=sum=0;
        CL(a,0);
        CL(b,0);
    }
     
    bool read(int &x)
    {
        x=0;
        char c;
        while(c=getchar()){
            if(c=='
    ') return false;
            if(c==' ') return true;
            x=x*10+c-'0';
        }
    }
     
    int main()
    {
        int T,n,m,cas=0;
        scanf("%d",&T);
        while(T--)
        {
            init();
            scanf("%d",&n);
            REP(i,1,n+1){
                scanf("%d",&p1[i]);
                sum+=p1[i];
                int x;
                getchar();
                while(read(x))
                {
                    a[x]=i;
                    maxn=max(maxn,x);
                }
                a[x]=i;
                maxn=max(maxn,x);
            }
            scanf("%d",&m);
            dinic.s=0,dinic.t=n+m+1;
            REP(i,1,m+1){
                scanf("%d",&p2[i]);
                sum+=p2[i];
                int x;
                while(read(x))
                {
                    b[x]=i;
                    maxn=max(maxn,x);
                }
                b[x]=i;
                maxn=max(maxn,x);
            }
            dinic.init(n+m+2,0,n+m+1);
            REP(i,1,n+1) dinic.addEdge(0,i,p1[i]);
            REP(i,1,m+1) dinic.addEdge(i+n,n+m+1,p2[i]);
            CL(vis,false);
            REP(i,1,maxn+1){
                if(!a[i]||!b[i]||vis[a[i]][b[i]]) continue;
                vis[a[i]][b[i]]=true;
                dinic.addEdge(a[i],b[i]+n,INF);
            }
            printf("Case %d:
    ",++cas);
            printf("%d
    ",sum-dinic.MaxFlow());
            if(T) printf("
    ");
        }
        return 0;
    }
    
    Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.
  • 相关阅读:
    Uva 12166 Equilibrium Mobile
    2015年7月实习经历以及一些感悟
    让键盘只数字键盘
    保留两位小数且,不四舍五入
    vuex的理解
    点击出现闪烁
    vue 添加样式分几种方法
    数据滞后的坑
    H5防止安卓手机软键盘弹出挤压页面导致变形的方法
    js 为false的几种情况
  • 原文地址:https://www.cnblogs.com/YCuangWhen/p/5263312.html
Copyright © 2020-2023  润新知