[鄭州培訓2012] 暴力摩托-並查集

如有錯誤,請留言提醒,不要坑到小朋友

Description

華英雄最喜歡玩暴力摩托,一個通宵之後,總算過了全關!正當他爲自己的成績洋洋得意的時候卻發現居然還有一個特別的附加關!華英雄雖然累得眼睛都睜不開了,但是他還是決定再試一試! 
這一關與以前的關不同,包含有N個站,之間連了M條雙向的通路!但每條路都規定了一個Speed值,在這條路上必須以這個速度前進!所以在前進的時候要頻繁的調整速度,這對魚類來說是很痛苦的,所以華英雄決定儘量使調整的幅度小一些,也就是使走過的路的速度最大值與最小值之差最小! 
可最近華英雄由於沉溺在暴力摩托中,已經荒廢了編程技術,所以只有請你來幫忙了!^_^ 

Input

第一行有2個正整數N , M , 分別表示站點數,路徑數. 接下來M行,每行有3個正整數 X, Y, V表示X, Y之間有一條路,其Speed值是V。再接下來是數K, 表示任務數, 下面K行,每行有一對正整數P,Q ,表示一個任務從P到Q. 
(1<=n<=200, 1<=m<=1000, 1<=K<=10) 

Output

對於每一個任務輸出一行,僅一個數,即最大速度與最小速度之差。 

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
這哪裏可以用到並查集呢
那就是判斷兩個點的聯通性
首先我們把所有的邊從小到大排序
然後我們一個一個添邊直到起點,終點聯通
#include<iostream>
int fa[201],x,y,n,m;
struct dd
{
	int x,y,len;
}line[1001];
int cmp(const void *a,const void *b)
{
	return (*(dd *)a).len>(*(dd *)b).len?1:-1;
}
int find(int f)
{
	if(fa[f]==f)return f;
	return fa[f]=find(fa[f]);
}
void work()
{
	int q,p,i,j,k;
	int ans=999999999;
	for(i=1;i<=m;i++)
	{
		for(j=1;j<=n;j++)
		fa[j]=j;
		for(j=i;j<=m;j++)
		{
			q=find(line[j].x);
			p=find(line[j].y);
			if(q!=p)fa[q]=p;
			if(find(x)==find(y))break;
		}
		if(fa[x]==fa[y])
		ans=ans<line[j].len-line[i].len?ans:line[j].len-line[i].len;                                             
	}
printf("%d\n",ans);	
}
int main()
{
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
	int i,j,k;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	 scanf("%d%d%d",&line[i].x,&line[i].y,&line[i].len);
	 qsort(line,m+1,sizeof(line[1]),cmp);
	scanf("%d",&k);
	for(i=1;i<=k;i++)
	 {
		scanf("%d%d",&x,&y);
		work();
 	} 
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章