题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4744

题意:三维空间n个点,每个点有一个wi值。每对点的距离定义为floor(欧拉距离),每对点之间建一条边的费用为两点间的距离,每对点之间可以建多条边。现要求对每一个点 i ,都在wi 个简单环上(每个点每条边都只经过一次),每条边只能属于一个简单环,简单环的费用为每条边的费用之和,问最小的建环费用。

思路:每个点拆成a、b两个点,从附加源点S到a连一条边,容量为wi,费用为0;从b到附加汇点T连一条边,容量为wi,费用为0。每两个点i, j之间,ai到bj连一条边,bi到aj连一条边,费用均为i, j的距离,容量均为无穷大。若最大流=sum{wi},那么有解,输出最小费用,否则输出-1。

struct node
{
    int u,v,next,cost,cap;
};

node edges[N*500];
int head[N],e;

void add(int u,int v,int cap,int cost)
{
    edges[e].u=u;
    edges[e].v=v;
    edges[e].cap=cap;
    edges[e].cost=cost;
    edges[e].next=head[u];
    head[u]=e++;
}

void Add(int u,int v,int cap,int cost)
{
    add(u,v,cap,cost);
    add(v,u,0,-cost);
}

int dis[N],S,T,nodeNum;
int maxFlow,minCost;

void SPFA()
{
    int i;
    for(i=0;i<=nodeNum;i++) dis[i]=INF;
    priority_queue<pair<int,int> > Q;
    dis[S]=0;
    Q.push(MP(0,S));
    int u,v,d;
    while(!Q.empty())
    {
        u=Q.top().second;
        d=-Q.top().first;
        Q.pop();

        if(dis[u]!=d) continue;
        for(i=head[u];i!=-1;i=edges[i].next)
        {
            v=edges[i].v;
            if(edges[i].cap&&dis[v]>d+edges[i].cost)
            {
                dis[v]=d+edges[i].cost;
                Q.push(MP(-dis[v],v));
            }
        }
    }
    for(i=0;i<=nodeNum;i++) dis[i]=dis[T]-dis[i];
}

int h[N];

int DFS(int u,int flow)
{
    if(u==T)
    {
        maxFlow+=flow;
        minCost+=flow*dis[S];
        return flow;
    }
    h[u]=1;
    int now=flow,i,v,temp;
    for(i=head[u];i!=-1;i=edges[i].next)
    {
        v=edges[i].v;
        if(edges[i].cap&&!h[v]&&dis[u]==dis[v]+edges[i].cost)
        {
            temp=DFS(v,min(now,edges[i].cap));
            edges[i].cap-=temp;
            edges[i^1].cap+=temp;
            now-=temp;
            if(!now) break;
        }
    }
    return flow-now;
}

int modifyLabel()
{
    int d=INF,i,j,v;
    for(i=1;i<=nodeNum;i++) if(h[i])
    {
        for(j=head[i];j!=-1;j=edges[j].next)
        {
            v=edges[j].v;
            if(edges[j].cap&&!h[v])
            {
                upMin(d,dis[v]+edges[j].cost-dis[i]);
            }
        }
    }
    if(d==INF) return 0;
    for(i=0;i<=nodeNum;i++) if(h[i]) dis[i]+=d;
    return 1;
}

int MCMF(int s,int t,int n)
{
    S=s; T=t; nodeNum=n;
    SPFA();
    maxFlow=minCost=0;
    int i;
    while(1)
    {
        while(1)
        {
            for(i=0;i<=nodeNum;i++) h[i]=0;
            if(!DFS(s,INF)) break;
        }
        if(!modifyLabel()) break;
    }
    return minCost;
}

struct point
{
    double x,y,z;

    void get()
    {
        cin>>x>>y>>z;
    }
};

point p[N];
int W[N],n,s,t;
int d[N][N];

int dist(point a,point b)
{
    double L=sqr(a.x-b.x)+sqr(a.y-b.y)+sqr(a.z-b.z);
    L=sqrt(L);
    L=floor(L);
    return L;
}

int main()
{
    Rush(n)
    {
        if(!n) break;
        int i,sum=0;
        FOR1(i,n) p[i].get(),RD(W[i]),sum+=W[i];
        int j;
        for(i=1;i<=n;i++) for(j=i+1;j<=n;j++)
        {
            d[i][j]=d[j][i]=dist(p[i],p[j]);
        }
        clr(head,-1); e=0;
        s=0; t=n*2+1;
        FOR1(i,n) Add(s,i,W[i],0),Add(i+n,t,W[i],0);
        FOR1(i,n)  FOR1(j,n) if(i!=j)
        {
            Add(i,n+j,INF,d[i][j]);
        }
        S=0;
        i64 ans=MCMF(s,t,t+1);
        if(maxFlow!=sum) ans=-1;
        PR(ans);
    }
}

  

HDU 4744 Starloop System(ZKW费用流)的更多相关文章

  1. HDU 4744 Starloop System(最小费用最大流)(2013 ACM/ICPC Asia Regional Hangzhou Online)

    Description At the end of the 200013 th year of the Galaxy era, the war between Carbon-based lives a ...

  2. zkw费用流+当前弧优化

    zkw费用流+当前弧优化 var o,v:..] of boolean; f,s,d,dis:..] of longint; next,p,c,w:..] of longint; i,j,k,l,y, ...

  3. 学习了ZKW费用流

    所谓ZKW费用流,其实就是Dinic. 若干年前有一个人发明了最小增广路算法,每次用BFS找一条增广路,时间O(nm^2) 然后被DinicD飞了:我们为什么不可以在长度不变时多路增广呢?时间O(n^ ...

  4. zkw费用流

    期末结束,竞赛生活继续开始,先怒刷完寒假作业再说 至于期末考试,数学跪惨,各种哦智障错,还有我初中常用的建系大法居然被自己抛至脑后,看来学的还是不扎实,以后数学要老老实实学.物理被永哥黑了两分,然后很 ...

  5. 【zkw费用流】[网络流24题]餐巾计划问题

    题目描述 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分(f ...

  6. CSU 1948: 超级管理员(普通费用流&&zkw费用流)

    Description 长者对小明施加了膜法,使得小明每天起床就像马丁的早晨一样. 今天小明早上醒来发现自己成了一位仓管员.仓库可以被描述为一个n × m的网格,在每个网格上有几个箱子(可能没有).为 ...

  7. BZOJ2673 [Wf2011]Chips Challenge 费用流 zkw费用流 网络流

    https://darkbzoj.cf/problem/2673 有一个芯片,芯片上有N*N(1≤N≤40)个插槽,可以在里面装零件. 有些插槽不能装零件,有些插槽必须装零件,剩下的插槽随意. 要求装 ...

  8. 图论-zkw费用流

    图论-zkw费用流 模板 这是一个求最小费用最大流的算法,因为发明者是神仙zkw,所以叫zkw费用流(就是zkw线段树那个zkw).有些时候比EK快,有些时候慢一些,没有比普通费用流算法更难,所以学z ...

  9. zkw费用流 学习笔记

    分析 记\(D_i\)为从\(S\)出发到\(i\)的最短路 最短路算法保证, 算法结束时 对于任意存在弧\((i,j)\)满足\(D_i + c_{ij}\ge D_j\) ① 且对于每个 \(j\ ...

随机推荐

  1. 几个Google中国的访问IP

    前面几个IP的访问速度比较快. 74.125.31.106 173.194.45.20 173.194.45.19 173.194.45.18 173.194.45.17 173.194.45.16 ...

  2. HTML页面处理以及资源文件的加载

    Javascript 异步加载详解 这篇文章很详细的介绍了HTML的页面处理以及资源文件的加载. 本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading ...

  3. Java正则表达式匹配例子

    Java正则表达式匹配例子 package com.ibm.test; import java.util.regex.Matcher; import java.util.regex.Pattern; ...

  4. POJ 1273 Drainage Ditches(网络流dinic算法模板)

    POJ 1273给出M条边,N个点,求源点1到汇点N的最大流量. 本文主要就是附上dinic的模板,供以后参考. #include <iostream> #include <stdi ...

  5. HDU 1385 Minimum Transport Cost (Dijstra 最短路)

    Minimum Transport Cost http://acm.hdu.edu.cn/showproblem.php?pid=1385 Problem Description These are ...

  6. JavaScript中函数的形参和实参的实现原理剖析

    我们都知道JS里面参数的传递是可以不一样的,比如我们有一个函数: <script type="text/javascript"> function one(a,b,c) ...

  7. 斐波那契数列公式算法-JS实现

    之前算斐波那契数列都是算前两个数相加实现的 比如0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181 ...

  8. HTML基本操作

    插入图片: 1.利用链接(静态) <img src="http://www.kmwzjs.com/useruploads/images/20101020_057600100825157 ...

  9. Spring学习总结(2)——Spring IOC的前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  10. C++运算符重载——重载二元运算符

    1.重载二元操作符的方法 二元运算符又称为双目运算符,即需要2个操作数的运算符,例如 + - * / 等. 运算符重载可以分为3种方式:类的非静态成员函数.类的友元函数.普通函数. 例如有 2 个操作 ...