UVA - 1395 Slim Span (最小生成树Kruskal)
Kruskal+并查集。
点很少,按边权值排序,枚举枚举L和R,并查集检查连通性。一旦连通,那么更新答案。
判断连通可以O(1),之前O(n)判的,第一次写的过了,后来T。。
#include<bits/stdc++.h> using namespace std; const int maxn = 101; const int maxe = maxn*maxn>>1; int n,m; int u[maxe],v[maxe],w[maxe]; int pa[maxn]; inline bool cmp(int a,int b) { return w[a]<w[b]; } int r[maxe]; inline void idxSort() { for(int i = 0; i < m; i++) r[i] = i; sort(r,r+m,cmp); } int Find(int x) { return x==pa[x]?x:pa[x]=Find(pa[x]); } int cnt,ans; inline void Union(int a,int b) { int s1 = Find(a),s2 = Find(b); if(s1 != s2){ pa[s1] = s2,cnt--; } } inline void initUFS() { for(int i = 1; i <= n; i++) pa[i] = i; cnt = n-1; } const int INF = 0x3f3f3f3f; int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m),n){ for(int i = 0; i < m; i++) scanf("%d%d%d",u+i,v+i,w+i); idxSort(); ans = INF; for(int i = 0; i < m; i++){ initUFS(); for(int j = i; j < m; j++){ int R = r[j]; Union(u[R],v[R]); if(!cnt) { ans = min(ans,w[R]-w[r[i]]); break; } } } printf("%d\n",ans==INF?-1:ans); } return 0; }