1. 程式人生 > >小 X 的道路修建

小 X 的道路修建

不能 道路修建 getchar() efi sta lin bit ota 接下來

題目描述

因為一場不小的地震, Y 省 n 個城市之間的道路都損壞掉了,省長希望小 X 將城市之間的道路重 修一遍。 很多城市之間的地基都被地震破壞導致不能修路了,因此可供修建的道路只有 m 條。因為施工隊伍 有限,省長要求用盡量少的道路將所有的城市連通起來,這樣施工量就可以盡量少。不過,省長為了表 示自己的公正無私,要求在滿足上述條件的情況下,選擇一種方案,使得該方案中最貴道路的價格和最 便宜道路的價格的差值盡量小,即使這樣的方案會使總價提升很多也沒關系。 小 X 現在手忙腳亂,希望你幫幫他。

輸入

第一行包含兩個整數 n; m。 接下來 m 行,每行包含三個整數 a; b; c,表示城市 a; b 之間可以修建一條價格為 c 的無向道路。

輸出

若存在合法方案,則第一行包含一個整數,表示最貴道路的價格和最便宜道路的價格的最小差值; 否則第一行包含一個整數 −1。

樣例輸入

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

樣例輸出

1686 LCT 裸題。
#pragma GCC optimize("-Ofast")
#include<bits/stdc++.h>
#define N 910007
using
namespace std; int n,m,ans=INT_MAX,ti; void read(int &x){ static char c; static int b; for (b=1,c=getchar();!isdigit(c);c=getchar()) if (c==-) b=-1; for (x=0;isdigit(c);c=getchar()) x=x*10+c-48; x*=b; } struct edge{ int x,y,z; inline bool operator <(const edge& A)const
{ return z<A.z; } }e[N]; namespace snow{ int ch[N][2],fa[N],r[N],mi[N],val[N],id,usd[N]; bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; } void rev(int x){ r[x]^=1; swap(ch[x][0],ch[x][1]); } void pushdown(int x){ if (!isroot(x)) pushdown(fa[x]); if (r[x]) { if (ch[x][0]) rev(ch[x][0]); if (ch[x][1]) rev(ch[x][1]); r[x]=0; } } void pushup(int x){ mi[x]=val[mi[ch[x][0]]]<val[mi[ch[x][1]]]?mi[ch[x][0]]:mi[ch[x][1]]; mi[x]=val[mi[x]]<val[x]?mi[x]:x; } void rotate(int x){ int y=fa[x],z=fa[y],l,r; if (ch[y][0]==x) l=0; else l=1; r=l^1; if (!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z; fa[ch[x][r]]=y; fa[y]=x; ch[y][l]=ch[x][r]; ch[x][r]=y; pushup(x); pushup(y); } void splay(int x){ pushdown(x); while (!isroot(x)) { int y=fa[x],z=fa[y]; if (!isroot(y)) { if (ch[y][0]==x^ch[z][0]==y) rotate(x); else rotate(y);} rotate(x); } } void access(int x) { int y=0; while (x) { splay(x); ch[x][1]=y; pushup(x); y=x; x=fa[x]; } } void beroot(int x){ access(x); splay(x); rev(x); } int root(int x) { access(x); splay(x); while (ch[x][0]) x=ch[x][0]; return x; } void link(int x,int y){ beroot(x); fa[x]=y; } void cut(int x,int y){ beroot(x); access(y); splay(y); if (ch[y][0]==x) ch[y][0]=0; fa[x]=0; } void sol() { for (int i=1;i<=m;i++) read(e[i].x),read(e[i].y),read(e[i].z); sort(e+1,e+m+1); ans=INT_MAX; for (int i=0;i<=n;i++) val[i]=INT_MAX; for (int i=1;i<=m;i++) val[n+i]=e[i].z; int to=1; for (int i=1;i<=m;i++) { beroot(e[i].x); if (root(e[i].y)!=e[i].x) { link(n+i,e[i].x); link(n+i,e[i].y); ti++; }else { id=mi[e[i].y]; usd[id-n]=1; cut(id,e[id-n].x); cut(id,e[id-n].y); link(n+i,e[i].x); link(n+i,e[i].y); } while (usd[to]) to++; if (ti==n-1) ans=min(ans,e[i].z-e[to].z); } printf("%d\n",ans==INT_MAX?-1:ans); } } signed main () { read(n); read(m); snow::sol(); }

小 X 的道路修建