• POJ 3469 Dual Core CPU | 最小割


    题面:

    有两个集合,现在又n个点,第i个点在A集合花费Ai代价,在B集合花费Bi代价
    然后又m个限制,每个限制是a,b,c,说a和b如果不在一个集合就会多花费c代价。

    现在要让每个点属于一个集合,求最小代价


    题解:

    相当于把n个点划分为两个集合,我们设A为源点S,B为汇点T,对于每个点向S和T连权值大小的边

    对于每个限制a,b,c,建双向边让a连b,b连a,大小都为c,求出图中的最小割,就是把n个点,划分为两个集合的最小代价

    又因为最小割==最大流,跑DINIC即可了.

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    #define N 20010
    #define M 800010
    #define INF 100000000
    using namespace std;
    int head[N],cur[N],lev[N],ecnt=1,S,T,n,m;
    queue <int> q;
    struct adj
    {
        int nxt,v,w;
    }e[2*M];
    void add(int u,int v,int w)
    {
        e[++ecnt].v=v,e[ecnt].w=w,e[ecnt].nxt=head[u],head[u]=ecnt;
        e[++ecnt].v=u,e[ecnt].w=0,e[ecnt].nxt=head[v],head[v]=ecnt;
    }
    inline int bfs()
    {
        int u,v;
        for (int i=S;i<=T;i++)
        lev[i]=-1,cur[i]=head[i];
        q.push(S),lev[S]=0;
        while (!q.empty())
        {
        u=q.front();
        for (int i=head[u];i;i=e[i].nxt)
        {
            if (e[i].w>0 && lev[v=e[i].v]==-1)
            lev[v]=lev[u]+1,q.push(v);
        }
        q.pop();
        }
        return lev[T]!=-1;
    }
    inline int Dinic(const int &u,const int &flow)
    {
        if (u==T) return flow;
        int res=0,v,delta;
        for (int &i=cur[u];i;i=e[i].nxt)
        {
        if (e[i].w>0 && lev[u]<lev[v=e[i].v])
        {
            delta=Dinic(v,min(e[i].w,flow-res));
            if (delta)
            {
            e[i].w-=delta;e[i^1].w+=delta;
            res+=delta;if (res==flow) break;
            }
        }
        }
        if (res!=flow) lev[u]=-1;
        return res;
    }
    inline int Maxflow()
    {
        int ans=0;
        while (bfs()) ans+=Dinic(S,INF);
        return ans;
    }
    inline void init()
    {
        memset(head,0,sizeof(head));
        ecnt=1;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        S=0,T=n+1;
        for (int i=1,a,b;i<=n;i++)
    	scanf("%d%d",&a,&b),add(S,i,a),add(i,T,b);
        for (int i=1,u,v,w;i<=m;i++)
    	scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);
        printf("%d",Maxflow());
        return 0;
    }
    
  • 相关阅读:
    转 博客园 各种大牛合集
    系统学习qsort1 尤其partition
    转 大整数乘法 1 复杂度分析
    【转】如何设计一个LRU Cache?
    转微软大牛 13道链表操作
    框架设计之旅(1)--数据的分层
    框架设计之旅(2)--数据分层之实际应用
    DB2相关问题及解决方法:
    框架设计之旅--启航篇
    如何挑选水货诺基亚手机
  • 原文地址:https://www.cnblogs.com/mrsheep/p/7942223.html
Copyright © 2020-2023  润新知