您的位置:首页 > 其它

[中等] UVa OJ 1395 Slim Span

2017-09-13 10:23 141 查看
题目描述

基本思路:

本题本质上就是让你从给定无向图的所有支撑树中找出边权值之差最小的那个,很像是一个变形的BST(最小生成树)问题,然而,BST问题可以通过贪心每次选择权值最小的那条边来解决,可本题不行,并没有类似的贪心策略,因此我们还得考虑枚举。因为本题要求的是权值之差最小,因此我们可以先排序,再按照这个序列顺序进行枚举(类似滑动窗口),这样可以使枚举量大大减少。

当然,本题需要判连通,采用并查集

具体代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <climits>

using namespace std;
const int maxn=100+4;
int n,m;
struct Edge
{
int u,v;
int d;
Edge(int tu,int tv,int td):u(tu),v(tv),d(td){}
bool operator < (const Edge& rhs) const
{
return d<rhs.d;
}
};
vector<Edge> edges;
vector<int> G[maxn];
int p[maxn];
inline int findFather(int x)
{
return p[x]==x?x:p[x]=findFather(p[x]);
}
int main()
{
// freopen("input.txt","r",stdin);
for(cin>>n>>m;n!=0;cin>>n>>m)
{
for(int i=0;i<=n;++i)
p[i]=i;
edges.clear();
for(int i=0;i<=n;++i)
G[i].clear();
for(int i=0;i<m;++i)
{
int a,b,c;
cin>>a>>b>>c;
edges.push_back(Edge(a,b,c));
G[a].push_back(edges.size()-1);
}
sort(edges.begin(),edges.end());
int ans=INT_MAX;
for(int l=0;l<m;++l)
{
for(int i=1;i<=n;++i)
p[i]=i;
int sn=n;
for(int r=l;r<m;++r)
{
int uf=findFather(edges[r].u);
int vf=findFather(edges[r].v);
if(uf!=vf)
{
p[uf]=vf;
if(--sn==1)
{
ans=min(ans,edges[r].d-edges[l].d);
break;
}
}
}
}
if(ans<INT_MAX)
cout<<ans<<endl;
else
cout<<"-1"<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BST 枚举 并查集