Slim Span UVA
阿新 • • 發佈:2018-12-11
Slim Span
題目大意:
給出m條邊,問使n個節點連成一幅連通圖的最大邊減去最小邊的最小值
思路:
對邊按照邊權排序,求出在邊權從小到大的邊序列中連續的可以使點連成圖的邊的最大值與最小值之差。再求暴力對比。
AC程式碼:
#include<algorithm> #include<cstdio> #include<iostream> using namespace std; const int inf=0x3f3f3f3f; struct Edge{ int u,v,w; Edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){} friend bool operator<(Edge a,Edge b) { return a.w<b.w; } }edge[10005]; int cnt; int fa[105]; int n; void rebuild() { for(int i=1;i<=n;i++){ fa[i]=i; } } int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); } bool merge(int x,int y) { int fx(find(x)),fy(find(y)); if(fx==fy) return false; fa[fx]=fy; return true; } void build(Edge e) { if(merge(e.u,e.v))cnt--; } int main() { int m; while(~scanf("%d%d",&n,&m)&&(n||m)) { for(int i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); edge[i]=Edge(u,v,w); } sort(edge+1,edge+1+m); int l,r; int flag=1; int minn=inf; for(l=1;l<=m;l++) { rebuild(); cnt=n; r=l; while(cnt>=2) { if(r==m+1){ flag=0; break; } build(edge[r]); r++; } if(!flag) break; minn=min(minn,edge[r-1].w-edge[l].w); } if(minn==inf) printf("-1\n"); else printf("%d\n",minn); } }