K:最小差异值
Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 1 Solved: 1
Description
X 省刚经历一场不小的地震,所有城市之间的道路都损坏掉了,所以省长想请你将城市之间的道路重修一遍。
因为很多城市之间的地基都被地震破坏导致不能修公路了,所以省长给定了你一些城市对,在这些城市对之间可以修公路,并且都有相应的价格。而且因为施工队伍有限,所以省长要求用尽量少的道路将所有的城市连通起来,这样施工量就可以尽量少,道路可视为无向边,且数据保证至少有一种连通的方案。不过,省长为了表示自己的公正无私,要求在满足上述条件的情况下,选择一种方案,使得该方案中最贵道路的价格和最便宜道路的价格的差值尽量小,即使这样的方案会使总价提升很多也没关系。
那么,请你尽快地安排一种合理的方案,满足省长的要求。
Input
第一行两个数 N,M,表示城市的个数以及可以修的公路数;
第二行开始 M 行,每行三个数 a,b,c,表示 a,b 之间可以修一条价值 c 的无向道路。
Output
一个数表示该方案中最大边减去最小边的值,要求要尽量的小。
Sample Input
5 10
1 2 9384
1 3 887
1 4 2778
1 5 6916
2 3 7794
2 4 8336
2 5 5387
3 4 493
3 5 6650
4 5 1422
Sample Output
1686
Hint
【样例说明】 选第 4,5,6,9 条边即可。
【数据说明】
100%数据满足 N<=M<=5000,0<c<=50000;
来源:CSUOJ
思路:kruskal算法,遍历从最小边开始往下依次生成最小生成树并让差值与上一次的差值比较,取最小即可。
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=2e5+5;
int fa[N];
int n;
int vis[N];
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
int merge(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx==fy)return 0;
else{
fa[fx]=fy;
return 1;
}
}
struct Edge{
int u,v,w;
bool operator < (const Edge&b)const {
return w<b.w;
}
}e[N];
void init()
{
for(int i=1;i<=n;i++)
fa[i]=i;
}
int main()
{
int W,m;
int cnt2;
char start,end;
while(scanf("%d%d",&n,&m)!=EOF){
init();
memset(e,0,sizeof(e));
cnt2=0;
for(int i=0;i<m;i++){
cin>>e[i].u>>e[i].v>>e[i].w;
}
int ans=INF;
std::sort(e,e+m);
for(int i=0;i<m;i++)
{
init();
int cnt=0;
for(int j=i;j<m;j++)
{
cnt+=merge(e[j].u,e[j].v);
if(cnt==n-1)
{
ans=min(ans,e[j].w-e[i].w);
break;
}
}
if(cnt<n-1)
break;
}
printf("%d\n",ans);
}
return 0;
}