zoukankan      html  css  js  c++  java
  • bzoj1497: [NOI2006]最大获利 最大权闭合子图

    新的技术正冲击着手机通讯市场,对于各大运营商来说,这既是机遇,更是挑战。THU集团旗下的CS&T通讯公司在新一代通讯技术血战的前夜,需要做太多的准备工作,仅就站址选择一项,就需要完成前期市场研究、站址勘测、最优化等项目。在前期市场调查和站址勘测之后,公司得到了一共N个可以作为通讯信号中转站的地址,而由于这些地址的地理位置差异,在不同的地方建造通讯中转站需要投入的成本也是不一样的,所幸在前期调查之后这些都是已知数据:建立第i个通讯中转站需要的成本为Pi(1≤i≤N)。另外公司调查得出了所有期望中的用户群,一共M个。关于第i个用户群的信息概括为Ai, Bi和Ci:这些用户会使用中转站Ai和中转站Bi进行通讯,公司可以获益Ci。(1≤i≤M, 1≤Ai, Bi≤N) THU集团的CS&T公司可以有选择的建立一些中转站(投入成本),为一些用户提供服务并获得收益(获益之和)。那么如何选择最终建立的中转站才能让公司的净获利最大呢?(净获利 = 获益之和 - 投入成本之和)
    题解:最大权闭合子图,对于一个有向图来说,每个节点有权值(可正可负),求找一张子图满足点权和最大,对于一条边u->v来说,如果u被选中了,那么v也要被选中,可以转化成最小割模型,点权和最大即正点权-最小割,最小割是s想正点权点连一条容量为点权的边,负点权点连一条容量为负点权的边,原图中的边容量为inf,那么对于这题来说只需要把边也看成点,跑一遍最小割即可

    /**************************************************************
        Problem: 1497
        User: walfy
        Language: C++
        Result: Accepted
        Time:2172 ms
        Memory:25288 kb
    ****************************************************************/
     
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
     
    using namespace std;
     
    const double eps=1e-6;
    const int N=55000+10,maxn=2000000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
     
    struct edge{
        int to,Next,c;
    }e[maxn];
    int s,t,cnt,head[N];
    void init()
    {
        cnt=0;
        memset(head,-1,sizeof head);
    }
    void add(int u,int v,int c)
    {
        e[cnt].to=v;
        e[cnt].c=c;
        e[cnt].Next=head[u];
        head[u]=cnt++;
        e[cnt].to=u;
        e[cnt].c=0;
        e[cnt].Next=head[v];
        head[v]=cnt++;
    }
    int dis[N];
    bool bfs()
    {
        queue<int>q;
        memset(dis,-1,sizeof dis);
        dis[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=head[x];~i;i=e[i].Next)
            {
                int y=e[i].to;
                if(dis[y]==-1&&e[i].c>0)
                {
                    dis[y]=dis[x]+1;
                    q.push(y);
                }
            }
        }
        return dis[t]!=-1;
    }
    int dfs(int u,int mx)
    {
        if(u==t)return mx;
        int flow=0,f;
        for(int i=head[u];~i;i=e[i].Next)
        {
            int x=e[i].to;
            if(dis[x]==dis[u]+1&&e[i].c>0&&(f=dfs(x,min(mx-flow,e[i].c))))
            {
                e[i].c-=f;
                e[i^1].c+=f;
                flow+=f;
            }
        }
        if(flow==0)dis[u]=-2;
        return flow;
    }
    int maxflow()
    {
        int ans=0,f;
        while(bfs())
        {
            while((f=dfs(s,inf)))ans+=f;
        }
        return ans;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        s=n+m+1,t=n+m+2;
        init();
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            int c;
            scanf("%d",&c);
            add(i,t,c);
        }
        for(int i=1;i<=m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);ans+=c;
            add(i+n,a,inf);
            add(i+n,b,inf);
            add(s,i+n,c);
        }
        printf("%d
    ",ans-maxflow());
        return 0;
    }
    /********************
     
    ********************/
    
  • 相关阅读:
    【python刷题】前缀和
    【python刷题】数组链表去重
    【python刷题】滑动窗口法
    【python刷题】二分查找
    【python刷题】广度优先搜索(BFS)
    【python刷题】回溯算法(深度优先搜索DFS)
    机器学习十讲-第三讲分类
    数学知识-质数&约数
    树与图的DFS与BFS
    桥梁保护与监控-开发进度(二)
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9130175.html
Copyright © 2011-2022 走看看