uva 1151 买还是建 buy or build 最小生成树 Kruskal

#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector> 
#define LL long long
using namespace std;

typedef struct edge{
	int s;
	int e;
	int w;
}edge;

typedef struct plan{
	int num;
	int cost;
	vector<int> city;
}plan;

int ans = 0;
int parent[10000];
int x[1005], y[1005];
plan Plan[10];
edge Edge[1000*1000+5];
edge Ed[1000*1000+5];

bool cmp(edge a, edge b){
	return a.w < b.w;
}

int find(int x)
{
	return parent[x]==x ? x:parent[x]=find(parent[x]);
}

bool merge(int x, int y)
{
	int fa = find(x);
	int fb = find(y);
	if(fa != fb)
	{
		parent[fa] = fb;
		return true;
	}
	else
		return false;
}

void init()
{
	for(int i = 0; i < 1050; i++)
		parent[i] = i;
}
		
int get_dis(int i, int j)
{
	return (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
}

int main()
{
	//freopen("ztest.txt","r",stdin);
	//freopen("zans.txt","w",stdout);
	int t;
	scanf("%d", &t);
	while(t--)
	{
		for(int i = 0; i < 10; i++)
			Plan[i].city.clear();
		ans = 0;
		int n, p;
		scanf("%d%d", &n, &p);
		for(int i = 0; i < p; i++)
		{
			scanf("%d%d", &Plan[i].num, &Plan[i].cost);
			for(int j = 0; j < Plan[i].num; j++)
			{
				int temp;
				scanf("%d", &temp);
				Plan[i].city.push_back(temp);
			}
		}
		for(int i = 1; i <= n; i++)
			scanf("%d%d", &x[i], &y[i]);
		int u = 0;
		for(int i = 1; i <= n; i++)
		for(int j = i+1; j <= n; j++)
		{
			int temp = get_dis(i, j);
			//printf("temp:%d\n",temp);
			Edge[u].e = i;
			Edge[u].s = j;
			Edge[u++].w = temp;
		}
		sort(Edge, Edge+u, cmp);
		for(int i = 1; i <= n; i++) 
	        parent[i] = i;
		int r = 0;
		for(int i = 0; i < u; i++)
			if(merge(Edge[i].s, Edge[i].e))
			{
				ans += Edge[i].w;
				Ed[r].s = Edge[i].s;
				Ed[r].e = Edge[i].e;
				Ed[r++].w = Edge[i].w;
			}
		for(int i = 0; i < 1<<p; i++)
		{
			int cost = 0;
			init();
			for(int j = 0; j < p; j++)	
			if(i&(1<<j))
			{
				cost += Plan[j].cost;
				int sta = Plan[j].city[0];
				for(int w = 0; w < Plan[j].city.size(); w++)
					merge(sta, Plan[j].city[w]);
			}
			for(int j = 0; j < r; j++)
				if(merge(Ed[j].s, Ed[j].e))
					cost += Ed[j].w;
			ans = min(ans, cost);
		}
		printf("%d\n", ans);
		if(t)
			printf("\n");
	}
	return 0;
}
			

猜你喜欢

转载自blog.csdn.net/wukongakk/article/details/81105260