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; }