「fjWC2014」生成树
Description
给定一个无向图,要求图中一个生成树,这个生成树中的最大边和最小边相差最小,输出这个差值
Input
每组测试数据一组样例
每组样例首先输入两个整数n, m (3 ≤ n ≤ 300, 0 < m ≤ n*(n-1)/2),表示该组样例中点和边的个数,之后每行三个整数x, y, s (0 ≤ x ≤ n-1, 0 ≤ y ≤ n-1, 1 ≤ s ≤ 10000),表示编号为x和编号为y的点之间有一条长度为s的边相连,保证给定的图联通,任意两点之间只有一条边相连
Output
对于每组样例,首先输出样例编号,之后输出最小差值,具体格式见sample output
Sample Input
3 3
0 1 220
1 2 120
2 0 160
4 5
2 3 80
1 3 80
0 1 180
2 1 200
3 0 140
Sample Output
40
60
注意:样例虽然给出三组输入数据,但是测试数据中每组输入只会有一组测试数据
数据范围 n m
1 ≤10 ≤45
2 ≤10 ≤45
3 ≤100 ≤4950
4 ≤100 ≤4950
5 ≤300 ≤20000
6 ≤300 ≤20000
7 ≤300 ≤44850
8 ≤300 ≤44850
9 ≤300 ≤44850
10 ≤300 ≤44850
本题与舒适的路线几乎相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; int n,m,ft[301],ans=0x7fffffff; struct data{int x,y,v;}e[45001]; bool cmp(data a,data b){return a.v<b.v;} int find(int x){return x==ft[x]?x:ft[x]=find(ft[x]);} int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v); sort(e+1,e+m+1,cmp); int start=1; while(start<=m) { int mx=-1,mn=-1; int t=0,i; for(int k=0;k<n;k++)ft[k]=k; for(i=start;i<=m;i++) { int p=find(e[i].x),q=find(e[i].y); if(p!=q){ ft[p]=q;t++; if(t==n-1){mx=e[i].v;break;} } } if(mx==-1)break; t=0; for(int k=0;k<n;k++)ft[k]=k; for(;i>0;i--) { int p=find(e[i].x),q=find(e[i].y); if(p!=q){ ft[p]=q;t++; if(t==n-1){mn=e[i].v;start=i+1;break;} } } if(mn==-1)break; ans=min(ans,mx-mn); } printf("%d\n",ans); return 0; } |