hdu oj 1102(Kruskal)

分析: 已经有n个村修好了路,问打通所有村庄的最小生成树,拿merge中的mark判断一下是否在树中

#include<algorithm>
#include<iostream>
#include<vector>
#include<bits/stdc++.h> 
#define maxn 110
using namespace std;

struct road{
	int x, y, dist;
	road(int ix, int iy, int idist){
		x = ix;
		y = iy;
		dist = idist;
	}
};
 
int n,roads,length;
vector<road> vec;
 
int pre[maxn];
bool yes[maxn][maxn];
 
void init(int n){
	for (int i = 1; i <= n; ++i)
		pre[i] = i;	
}
 
int find(int v)
{
	int t1,t2=v;
	while(v!=pre[v]) v=pre[v];
	while(pre[t2]!=v)
	{
		t1=pre[t2];
		pre[t2]=v;
		t2=t1;
	}
	return v;
}
 
bool merge(int x, int y){
	int fy = find(y);
	int fx = find(x);
	bool mark = false;
 
	if (fx != fy){
		pre[fx] = fy;
		mark = true;
	}
 
	return mark;
}
 
bool cmp(road a, road b)
{return a.dist < b.dist;}
 
int main(){
	int dist, t, x, y;
	while (cin>>n){
		vec.clear();
		memset(yes, 0, sizeof(yes));
		for (int i = 1; i <= n; ++i){
			for (int j = 1; j <= n; ++j){
				scanf("%d", &dist);
				if (i == j || i > j)continue;//重复的路径不进行添加
				vec.push_back(road(i, j, dist));
			}
		}
 
		sort(vec.begin(), vec.end(), cmp);
		init(n);
		scanf("%d", &t);
 
		while (t--){
			scanf("%d %d", &x, &y);
			merge(x, y);
			yes[x][y] = true;
		}
 
		length = 0;
		vector<road>::iterator it;
		for (it=vec.begin();it!=vec.end();++it){
			x = (*it).x;
			y = (*it).y;
			dist = (*it).dist;
			if (yes[x][y])continue;
			if (merge(x, y))length += dist;
		}
 
		printf("%d\n", length);
	}
	return 0;
}

看的iaccepted大佬的

发布了183 篇原创文章 · 获赞 31 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/mlm5678/article/details/104707191