poj 3522(最小生成树应用)
题目链接:http://poj.org/problem?id=3522思路:题目要求最小生成树中最大边与最小边的最小差值,由于数据不是很大,我们可以枚举最小生成树的最小边,然后kruskal求最小生成树,直到不能生成生成树为止,然后取最小的差值即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 111 7 #define inf 1<<30 8 9 struct Edge{ 10 int u,v; 11 int len; 12 }edge[MAXN*MAXN]; 13 int parent[MAXN]; 14 int n,m; 15 16 void Initiate() 17 { 18 for(int i=1;i<=n;i++){ 19 parent[i]=i; 20 } 21 } 22 23 int Find(int x) 24 { 25 if(x==parent[x]){ 26 return parent[x]; 27 } 28 parent[x]=Find(parent[x]); 29 return parent[x]; 30 } 31 32 void Union(int u,int v) 33 { 34 int r1=Find(u),r2=Find(v); 35 if(r1==r2)return ; 36 parent[r1]=r2; 37 } 38 39 int cmp(const Edge &p,const Edge &q) 40 { 41 return p.len<q.len; 42 } 43 44 int Kruskal(int id) 45 { 46 int count=0,MIN=inf,MAX=-inf; 47 for(int i=0;i<m;i++){ 48 if(edge[i].len<edge[id].len)continue; 49 int u=edge[i].u,v=edge[i].v; 50 if(Find(u)!=Find(v)){ 51 MIN=min(MIN,edge[i].len); 52 MAX=max(MAX,edge[i].len); 53 count++; 54 Union(u,v); 55 if(count==n-1)return MAX-MIN; 56 } 57 } 58 return -1; 59 } 60 61 62 63 int main() 64 { 65 while(~scanf("%d%d",&n,&m)){ 66 if(n==0&&m==0)break; 67 for(int i=0;i<m;i++){ 68 scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].len); 69 } 70 sort(edge,edge+m,cmp); 71 int ans=inf; 72 for(int i=0;i<m;i++){ 73 Initiate(); 74 int tmp=Kruskal(i); 75 if(tmp==-1)break; 76 ans=min(ans,tmp); 77 } 78 if(ans!=inf){ 79 printf("%d\n",ans); 80 }else 81 printf("-1\n"); 82 } 83 return 0; 84 }