HDU 4744 Starloop System(ZKW最小费用最大流)

思路:建图是显而易见的不过用普通的最小费用最大流超时了...改用ZKW才过了


#include<bits/stdc++.h>
using namespace std;
const int maxn = 210;
const int maxm = 210*210*2;
#define INF 1e9
struct ZKW_flow{
	int st,ed,ecnt,n;
	int head[maxn];
	int cap[maxm],cost[maxm],to[maxm],next[maxm];
	void init()
	{
		memset(head,0,sizeof(head));
		ecnt=2;
	}
	void addedge(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 d[maxn];
	void spfa()
	{
		for(int i = 1;i<=n;i++)
			d[i]=INF;
		priority_queue<pair<int,int> >q;
		d[st]=0;
		q.push(make_pair(0,st));
		while (!q.empty())
		{
			int u = q.top().second,di=-q.top().first;
			q.pop();
			if (d[u]!=di)continue;
			for (int p = head[u];p;p=next[p])
			{
				int &v = to[p];
				if (cap[p] && d[v]>di+cost[p])
				{
					d[v]=di+cost[p];
					q.push(make_pair(-d[v],v));
				}
			}
		}
		for (int i = 1;i<=n;i++) d[i]=d[ed]-d[i];
	}

    int minCost,maxFlow;
	bool use[maxn];

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

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

	int min_cost_flow(int ss,int tt,int nn)
	{
		st=ss,ed=tt,n=nn;
		minCost=maxFlow=0;
		spfa();
		while (1){
			while (1){
				for (int i = 1;i<=n;i++) use[i]=0;
				if (!add_flow(st,INF)) break;
			}
			if (!modify_label()) break;
		}
		return minCost;
	}
}zkw;
struct Point
{
	int x,y,z,w;
}point[maxn];
int cal(int i,int j)
{
	double xx = point[i].x-point[j].x;
	double yy = point[i].y-point[j].y;
	double zz = point[i].z-point[j].z;
	return (int)sqrt(xx*xx+yy*yy+zz*zz); 
}
int main()
{
    int n;
    while (scanf("%d",&n)!=EOF && n)
	{
		int sum = 0;
		for (int i = 1;i<=n;i++)
		{
			scanf("%d%d%d%d",&point[i].x,&point[i].y,&point[i].z,&point[i].w);
			sum+=point[i].w;
		}
        zkw.init();        
		int s = 2*n+1;
		int t = s+1;
		for (int i = 1;i<=n;i++)
		{
			zkw.addedge(s,i,point[i].w,0);
			zkw.addedge(i+n,t,point[i].w,0);
			for (int j = i+1;j<=n;j++)
			{
				int co = cal(i,j);
				zkw.addedge(i,j+n,INF,co);
				zkw.addedge(j,i+n,INF,co);
			}
		}
		int ans = zkw.min_cost_flow(s,t,t);
		if (zkw.maxFlow != sum)
			ans=-1;
		printf("%d\n",ans);
	}	
}


Description

At the end of the 200013  th year of the Galaxy era, the war between Carbon-based lives and Silicon civilization finally comes to its end with the Civil Union born from the ruins. The shadow fades away, and the new-born Union is opening a new page. 

Although the war ended, the affect of the war is far from over. Now the council is busy fixing the transportation system. Before the war, all the stars were connected with artificial wormholes which were destroyed during the war. At the same time, natural wormholes are breaking down with the growing traffic. A new traffic system is on the schedule. 

As two civilizations combine, the technology integrates. Scientists find a new traffic system called the Starloop System. 

This system is made up of several starloops. People build a starway to connect two stars. A startloop is a closed path with no repetitions of stars or starways allowed, other than the repetition of the starting and ending star. And a starloop contains at least two starts and two starways. A startloop's cost is the sum of the length of all the starways in it. Length of a starway connecting two stars is floor(x), which x is the euclidean distance between two stars. You can build more than one starway between any two stars, but one starway can only belongs to one starloop. 



As the picture above shows, there are two starloops. One is blue and the other one is brown. 

As a starloop is set up, each star on the starloop will get a unit of star-energy. So the two blue stars can get one unit of star-energy, and at the same time the black two stars can get two units because they both belong to two starloops. When a star earns a certain number of energy units, the transporter on that star will be activated. One can easily travel between any two stars whose transporter is activated. 

Now the council wants to know the minimal cost to build a starloop system on all the stars . In other words, every star's transporter should be activated
 

Input

There are multiple test cases. 
For each test case: 
There is a line with one integer n which is the number of stars. 

The following n lines each describes a star by four integers xi, yi, zi and wi, defined as the spatial coordinate and the number of energy units the star needs to activate the transporter. Please NOTE that getting more than wi energy units will put the star in a dangerous situation, so it is not allowed. 
The input ends with n = 0. 

1<=n<=100
|xi|,|yi|,|zi|<=200
wi<=50


 

Output

For each test case, output one line that contains an integer equals to the minimal cost you can get. If there is no solution, just output -1;
 

Sample Input

        
        
        
        
3 0 0 2 1 0 2 0 1 2 0 0 1 3 0 0 2 2 0 2 0 1 2 0 0 1 3 0 0 2 3 0 2 0 1 2 0 0 1 0
 

Sample Output

        
        
        
        
6 8 -1
 


你可能感兴趣的:(HDU 4744 Starloop System(ZKW最小费用最大流))