hdu1598(枚举法+并查集)

find the most comfortable road

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2384    Accepted Submission(s): 998


Problem Description
XX星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对 Flycar的“舒适度”有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服 ,(理解为SARS的限速要求,flycar必须瞬间提速/降速,痛苦呀 ),
但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。
 

Input
输入包括多个测试实例,每个实例包括:
第一行有2个正整数n (1<n<=200)和m (m<=1000),表示有N个城市和M条SARS。
接下来的行是三个正整数StartCity,EndCity,speed,表示从表面上看StartCity到EndCity,限速为speedSARS。speed<=1000000
然后是一个正整数Q(Q<11),表示寻路的个数。
接下来Q行每行有2个正整数Start,End, 表示寻路的起终点。
 

Output
每个寻路要求打印一行,仅输出一个非负整数表示最佳路线的舒适度最高速与最低速的差。如果起点和终点不能到达,那么输出-1。
 

Sample Input
   
   
   
   
4 4 1 2 2 2 3 4 1 4 1 3 4 2 2 1 3 1 2
 

Sample Output
   
   
   
   
1 0
 
本题暂没想到好的方法,就用并查集
枚举最短边,然后循环查找符合条件的生成树(并查集的操作)
询问次数不高,且边数不多,枚举法可以奏效,时间复杂度为O(q*m*m*log(n)),此题不会超时。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

//边节点信息
struct node
{
	int st1,st2,cost;
}Edge[1000+10];
int par[200+10];
const int INF=1<<30;

int cmp(const void *a,const void *b)
{
	node *aa=(node *)a;
	node *bb=(node *)b;
	return aa->cost-bb->cost;
}

int Get_par(int a)
//获得父亲节点
{
	if(par[a]==a)
		return par[a];
	par[a]=Get_par(par[a]);
	return par[a];
}

int min(int a,int b)
{
	return a<b?a:b;
}

int main()
{
	int i,j,n,m,k,s,e,Min,pa,pb;
	while(~scanf("%d%d",&n,&m))
	{
		for(i=1;i<=m;i++)
			scanf("%d%d%d",&Edge[i].st1,&Edge[i].st2,&Edge[i].cost);

		//从小到大对边上的速度排序
		qsort(Edge+1,m,sizeof(node),cmp);

		scanf("%d",&k);
		while(k--)
		{
			Min=INF;
			scanf("%d%d",&s,&e);

			//枚举速度最小的边
			for(i=1;i<=m;i++)
			{
				//初始化为单个子集
				for(j=1;j<=n;j++)
					par[j]=j;

				//依次加边到并查集中
				for(j=i;j<=m;j++)
				{
					pa=Get_par(Edge[j].st1);
					pb=Get_par(Edge[j].st2);
					if(pa!=pb)par[pa]=pb;
					//起点和终点联通,退出
					if(Get_par(s)==Get_par(e))
					{
						Min=min(Min,Edge[j].cost-Edge[i].cost);
						break;
					}
				}
			}
		
			if(Min==INF)
				printf("-1\n");
			else 
				printf("%d\n",Min);
		}
	}
	return 0;
}

 

你可能感兴趣的:(数据结构,并查集,生成树,枚举法)