HDU 4744 Starloop System(ZKW最小費用最大流)
阿新 • • 發佈:2018-12-28
打完才發現,這不就是我一直打的SPFA+多路增廣+vis防走環嗎。。。。。
AC Code:
#include<bits/stdc++.h> #define maxn 305 #define maxm 200005 #define inf 0x3f3f3f3f using namespace std; int info[maxn],Prev[maxm],to[maxm],cap[maxm],cst[maxm],cnt_e; inline void Node(int u,int v,int c,int ct){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cst[cnt_e]=ct,cap[cnt_e]=c; } inline void Line(int u,int v,int c,int ct){ Node(u,v,c,ct),Node(v,u,0,-ct); } int n,x[maxn],y[maxn],z[maxn],w[maxn]; int S,T,dis[maxn],acst,tot; inline int sqr(int a){ return a*a; } bool vis[maxn]; inline bool SPFA() { memset(dis,0x3f,sizeof dis); static queue<int>q; static int inq[maxn]; dis[T] = 0;q.push(T); for(int now;!q.empty();) { now = q.front();q.pop(); for(int i=info[now];i;i=Prev[i]) if(cap[i^1] && dis[to[i]] > dis[now] + cst[i^1]) { dis[to[i]] = dis[now] + cst[i^1]; if(!inq[to[i]]) inq[to[i]] = 1, q.push(to[i]); } inq[now] = 0; } return dis[S] < 0x3f3f3f3f; } int aug(int now,int Max) { if(now == T) return acst += Max * dis[S] , Max; vis[now] = 1; int st = Max , inc; for(int i=info[now];i && st;i=Prev[i]) if(cap[i] && dis[now] - cst[i] == dis[to[i]] && !vis[to[i]]) { inc = aug(to[i],min(cap[i],st)); st-=inc,cap[i]-=inc,cap[i^1]+=inc; } vis[now] = 0; return Max - st; } int main() { for(;~scanf("%d",&n) && n;) { int stm = 0;acst=0; tot = 2 * n; S = ++tot , T = ++tot; memset(info,0,sizeof info),cnt_e=1; for(int i=1;i<=n;i++) { scanf("%d%d%d%d",&x[i],&y[i],&z[i],&w[i]); Line(S,i,w[i],0),Line(i+n,T,w[i],0); stm+=w[i]; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j) { int ds = floor(sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j])+sqr(z[i]-z[j]))); Line(i,j+n,inf,ds); } for(;SPFA();) stm-=aug(S,inf); if(stm) acst = -1; printf("%d\n",acst); } }