给你一个有n个点和m条边的无向连通图,每条边都有一个权值w.
我们定义,对于一条路径,它的Charm value为该路径上所有边的权值的最大值与最小值的差.
询问从1到n的所有路径的Charm value的最小值.
Input
第一行有两个整数n,m(1≤n≤200,n−1≤m≤1000),表示该图有nn个点和mm条边.
接下来m行,每行三个整数u,v,w(1≤u,v≤n,1≤w≤1000000),表示点uu和点vv之间有一条权值为w的边.
Output
输出一个数,即从1到n的所有路径的Charm value的最小值.
Sample input and output
Sample Input | Sample Output |
---|---|
4 4 3 4 1 2 3 2 1 2 4 2 4 3 |
1 |
Source
2017 UESTC Training for Graph Theory
思路
首先,我们要找一条从1到n路径,使得路径上权重小的尽量大、权重大的尽量小
这就和Kruskal算法贪心的思想不谋而合
对边的权重按从小到大进行排序,从i=0开始对j>=i的边集构建最小生成树,对每个i求一个Charm value(可能对于某个i不存在Charm value),最后取最小值就OK了
#include <iostream> #include <cstdlib> #include <algorithm> using namespace std; struct edge{ int u,v,w; }; int V,E,id[210]; edge e[1010]; bool cmp(const edge &a,const edge &b) { return a.w<b.w; } int find(int x) { return (x==id[x])?x:(id[x]=find(id[x])); } int main() { int ru,rv,charmvalue=1000010; cin>>V>>E; for (int i=0; i<E; i++) cin>>e[i].u>>e[i].v>>e[i].w; sort(e, e+E, cmp); for (int i=0; i<E;i++) { for (int k=0; k<=V; k++) id[k]=k; for (int j=i; j<E; j++) { ru=find(e[j].u); rv=find(e[j].v); if (ru==rv) continue; id[ru]=rv; if (find(1)==find(V)) { charmvalue=min(charmvalue,abs(e[i].w-e[j].w)); break; } } } cout<<charmvalue; }