暴力摩托

暴力摩托

Description

N个站,之间连了M条双向的通路!但每条路都规定了一个速度的限制值,在这条路上必须以这个速度前进!所以在前进的时候要调整速度,现决定尽量使调整的幅度小一些,也就是使走过的路的速度最大值与最小值之差最小!

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

 

思路

题目给出点数n,边数m,x与y之间有长度为v的双向边。使从a走到b的路径中(max v-min v)最小。

把边按v升序排列,循环枚举i:1-m,再嵌套枚举j:i-m,认为这条路径是由第i条边到第j条边组成的。每次加入一条边,那么这条边的2个端点就为同一父亲,之后检查a,b是否为同一个父亲,如果是,那么a,b就连通了,(max v-min v)=(car[j].v-car[i].v),ans取min;否则继续加边。

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,k,maxx,minn,a,b,t1,t2,d[201],ans,kk;
struct note//结构体 
{
	int x,y,v;
}car[1010];
bool cmp(note x,note y)//结构体按v升序排列 
{
	return x.v<y.v;
}
int find(int x)//找父亲+路径压缩 
{
	if(d[x]!=x)
		d[x]=find(d[x]);
	return d[x];	
}
void check()
{
	ans=2147483647;
	for(int i=1;i<=m;i++)
	{
		for(int i=1;i<=200;i++)
			d[i]=i;//注意:每次都要重置 
		for(int j=i;j<=m;j++)
		{
			t1=find(car[j].x);
			t2=find(car[j].y);
			if(t1!=t2)
				d[t1]=t2;
			if(find(a)==find(b))//a,b连通了 
			{
				ans=min(ans,(car[j].v-car[i].v));
				break;
			}
		}
	}
	printf("%d\n",ans);	
}
int main()
{
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++)
		scanf("%d %d %d",&car[i].x,&car[i].y,&car[i].v);	
	sort(car+1,car+1+m,cmp);//排序	
	scanf("%d",&k);
	for(kk=1;kk<=k;kk++)
	{
		scanf("%d %d",&a,&b);
		check();
	} 
	return 0;
} 


每次从一个新的i开始加边之前,要把所有点的父亲都设为自己。

通过并查集,我们1.可以连通两点。2.判断是否连通。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值