hdu 4744 最小费用流

#include <cstdio>
#include <queue>
#include <cstring>
#include <cmath>
#define mul(a) (a)*(a)
using namespace std;

const int Maxn = 210;
const int Maxm = 100010;
const int inf = 0x3f3f3f3f;

struct ZKW_flow{
    int st, ed, ecnt, n;
    int head[Maxn];
    int cap[Maxm], cost[Maxm], to[Maxm], next[Maxm];

    void init(){
        memset(head, -1, sizeof(head));
        ecnt = 2;
    }

    void add(int u, int v, int cc, int ww){
        cap[ecnt] = cc; cost[ecnt] = ww; to[ecnt] = v;
        next[ecnt] = head[u]; head[u] = ecnt++;
        cap[ecnt] = 0; cost[ecnt] = -ww; to[ecnt] = u;
        next[ecnt] = head[v]; head[v] = ecnt++;
    }

    int dis[Maxn];

    void SPFA(){
        for(int i = 0; i <= n; ++i) dis[i] = inf;
        priority_queue<pair<int, int> > Q;
        dis[st] = 0;
        Q.push(make_pair(0, st));
        while(!Q.empty()){
            int u = Q.top().second, d = -Q.top().first;
            Q.pop();
            if(dis[u] != d) continue;
            for(int p = head[u]; p!=-1; p = next[p]){
                int &v = to[p];
                if(cap[p] && dis[v] > d + cost[p]){
                    dis[v] = d + cost[p];
                    Q.push(make_pair(-dis[v], v));
                }
            }
        }
        for(int i = 0; i <= n; ++i) dis[i] = dis[ed] - dis[i];
    }

    int minCost, maxFlow;
    bool use[Maxn];

    int add_flow(int u, int flow){
        if(u == ed){
            maxFlow += flow;
            minCost += dis[st] * flow;
            return flow;
        }
        use[u] = true;
        int now = flow;
        for(int p = head[u]; p!=-1; p = next[p]){
            int &v = to[p];
            if(cap[p] && !use[v] && dis[u] == dis[v] + cost[p]){
                int tmp = add_flow(v, min(now, cap[p]));
                cap[p] -= tmp;
                cap[p^1] += tmp;
                now -= tmp;
                if(!now) break;
            }
        }
        return flow - now;
    }

    bool modify_label(){
        int d = inf;
        for(int u = 0; u <= n; ++u) if(use[u])
            for(int p = head[u]; p!=-1; p = next[p]){
                int &v = to[p];
                if(cap[p] && !use[v]) d = min(d, dis[v] + cost[p] - dis[u]);
            }
        if(d == inf) return false;
        for(int i = 0; i <= n; ++i) if(use[i]) dis[i] += d;
        return true;
    }

    int ZKW(int ss, int tt, int nn){
        st = ss, ed = tt, n = nn;
        minCost = maxFlow = 0;
        SPFA();
        while(true){
            while(true){
                for(int i = 0; i <= n; ++i) use[i] = 0;
                if(!add_flow(st, inf)) break;
            }
            if(!modify_label()) break;
        }
        return minCost;
    }
} G;
int w[Maxn];
struct Point{
    int x,y,z;
}p[Maxn];
int DIS(Point a,Point b)
{
    return (int)sqrt(1.0*mul(a.x-b.x)+1.0*mul(a.y-b.y)+1.0*mul(a.z-b.z));
}
int main()
{
    int n,i,j,sum;
    while(scanf("%d",&n),n){
        G.init();
        sum=0;
        for(i=1;i<=n;i++){
            scanf("%d%d%d%d",&p[i].x,&p[i].y,&p[i].z,&w[i]);
            sum+=w[i];
        }
        for(i=1;i<=n;i++){
            G.add(0,i,w[i],0);
            G.add(i+n,2*n+1,w[i],0);
            for(j=i+1;j<=n;j++){
                int cost=DIS(p[i],p[j]);
                G.add(i,j+n,inf,cost);
                G.add(j,i+n,inf,cost);
            }
        }
        int ans=G.ZKW(0,2*n+1,2*n+2);
        if(G.maxFlow==sum)
        printf("%d\n",ans);
        else
        printf("-1\n");
    }
    return 0;
}

 

posted @ 2013-09-17 18:02  fangguo  阅读(281)  评论(0编辑  收藏  举报