HDU1598 find the most comfortable road (最小生成树,并查集的应用)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1598

题目大意:就是说有一个很奇葩的星球,假设有n个城市和m条路,每条路有自己的最大速度。现在给你起点和终点,要你求出一条路线是的你从起点可以到达终点并且这条路线中的速度的最大值和最小值是最小的。

题目思路:该题用到最小生成树的算法,,使用克鲁斯卡尔。。先将道路权值自小到大排序,再依次枚举权值下限,每次枚举一个下限时,初始化一次,然后Kruskal算法直到起点和终点两点被连通,记录这一路的极值。接着循环枚举下一个下限,即比前一个下限大一点的权值。直到 所有权值被枚举完,此时极值中的最小值就得到了。

参考代码:

#include<iostream>
using namespace std;
#include<algorithm>
#define INF 100000000
#define MAX 250
int n,m;
int parent[250];
struct node
{
	int u;
	int v;
	int w;
}map[1005];
bool cmp(node a,node b)
{
	return a.w<b.w;
}
void UFset()
{
	int i;
	for(i=0;i<=n;i++)
		parent[i]=-1;
}
int Find(int x)
{
	int s;
	int t;
	for(s=x;parent[s]>0;s=parent[s]);
	while(s!=x)
	{
		t=parent[x];
		parent[x]=s;
		x=t;
	}
	return s;
}
int Union(int R1,int R2)
{
	int r1=Find(R1),r2=Find(R2);
	int t=parent[r1]+parent[r2];
	if(r1==r2)
		return 0;
	if(parent[r1]>parent[r2])
	{
		parent[r1]=r2;
		parent[r2]=t;
	}
	else
	{
		parent[r2]=r1;
		parent[r1]=t;
	}
	return 1;
}
int main()
{
	while(cin>>n>>m)
	{
		int i;
		for(i=0;i<m;i++)
		{
			cin>>map[i].u>>map[i].v>>map[i].w;
		}
		sort(map,map+m,cmp);
		int Q,s,e;
		cin>>Q;
		while(Q--)
		{
			cin>>s>>e;
			int min=INF;
			for(i=0;i<m;i++)
			{
				UFset();	
				for(int j=i;j<m;j++)
				{
					if(Union(map[j].u,map[j].v)==1)
					{
						if(Find(s)==Find(e))
						{
							if(min>(map[j].w-map[i].w))
							{
								min=map[j].w-map[i].w;
								break;
							}
						}
					}
				}
			}
			if(min==INF)
				cout<<"-1"<<endl;
			else
				cout<<min<<endl;
		}
	}
	return 0;
}


你可能感兴趣的:(HDU1598 find the most comfortable road (最小生成树,并查集的应用))