标签:return pen src splay print pac min poj stream
链接:http://poj.org/problem?id=3522
题意:给你N个点,M条边(无向的);让你求一个生成树它具有:最大边权与最小边权的差是最小的。
分析:使用kru算法求生成树;当我们用最小边求取了生成树后,去除最小边,继续再求生成树,只需要每次求完生成树后跟新答案就可以了;复杂度O(M*M),因为边不多,可以实现。
1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #include<algorithm> 5 #include<cstring> 6 using namespace std; 7 #define ll long long 8 #define ull unsigned long long 9 #define mems(a,b) memset(a,b,sizeof(a)) 10 const int maxn=1e5+10; 11 const int inff=1e9+7; 12 int N,M; 13 int fa[maxn],pos[maxn]; 14 struct EDGE{ 15 int st,en,len; 16 bool operator<(const EDGE &a)const{ 17 return len<a.len; 18 } 19 }edge[maxn]; 20 21 int find_(int x){ 22 if(x==fa[x]) 23 return x; 24 fa[x]=find_(fa[x]); 25 return fa[x]; 26 } 27 28 int kru(){ 29 int ans=inff; 30 for(int k=1;k<=M;k++){ 31 int cnt=0; 32 int temp=inff; 33 for(int i=1;i<=N;i++) 34 fa[i]=i; 35 for(int i=k;i<=M;i++){ 36 int x=find_(edge[i].st); 37 int y=find_(edge[i].en); 38 int len=edge[i].len; 39 if(x!=y){ 40 fa[x]=y; 41 cnt++; 42 if(cnt==N-1){ 43 temp=len-edge[k].len; 44 break; 45 } 46 } 47 } 48 ans=min(ans,temp); 49 } 50 if(ans==inff) 51 ans=-1; 52 return ans; 53 } 54 55 int main() 56 { 57 while(scanf("%d%d",&N,&M)&&(N+M)){ 58 for(int i=1;i<=M;i++){ 59 scanf("%d%d%d",&edge[i].st,&edge[i].en,&edge[i].len); 60 } 61 sort(edge+1,edge+1+M); 62 63 printf("%d\n",kru()); 64 } 65 return 0; 66 }
1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #include<algorithm> 5 #include<cstring> 6 using namespace std; 7 #define ll long long 8 #define ull unsigned long long 9 #define mems(a,b) memset(a,b,sizeof(a)) 10 const int maxn=1e5+10; 11 const int inff=1e9+7; 12 int N,M; 13 int fa[maxn]; 14 struct EDGE{ 15 int st,en,len; 16 bool operator<(const EDGE &a)const{ 17 return len<a.len; 18 } 19 }edge[maxn]; 20 21 int find_(int x){ 22 if(x==fa[x]) 23 return x; 24 fa[x]=find_(fa[x]); 25 return fa[x]; 26 } 27 28 int kru(){ 29 int ans=inff; 30 for(int k=1;k<=M;k++){ 31 int cnt=0; 32 int temp=inff; 33 for(int i=1;i<=N;i++) 34 fa[i]=i; 35 for(int i=k;i<=M;i++){ 36 int x=find_(edge[i].st); 37 int y=find_(edge[i].en); 38 int len=edge[i].len; 39 if(x!=y){ 40 fa[x]=y; 41 cnt++; 42 if(cnt==N-1){ 43 temp=len-edge[k].len; 44 break; 45 } 46 } 47 } 48 ans=min(ans,temp); 49 } 50 if(ans==inff) 51 ans=-1; 52 return ans; 53 } 54 55 int main() 56 { 57 while(scanf("%d%d",&N,&M)&&(N+M)){ 58 for(int i=1;i<=M;i++){ 59 scanf("%d%d%d",&edge[i].st,&edge[i].en,&edge[i].len); 60 } 61 sort(edge+1,edge+1+M); 62 63 printf("%d\n",kru()); 64 } 65 return 0; 66 }
标签:return pen src splay print pac min poj stream
原文地址:https://www.cnblogs.com/Y-Meng/p/9282999.html