zoukankan      html  css  js  c++  java
  • POJ 3522 最大边与最小边差值最小的生成树

    题目链接: http://poj.org/problem?id=3522

    题目大意:

      给定一个简单图,n个点,m条边( 1<=n<=100,0 ≤ m ≤ n(n − 1)/2 ),要求一颗生成树,使得其最大边与最小边的差值是所有生成树中最小的,输出最小的那个差值。

    分析:

      类似于kruskal算法求最小生成树,将所有边按权值大小排升序,e1,e2,e3,...em。

      枚举每条边ei,对ei,ei+1,ei+2,ei+3...进行求生成树,不断更新差值得到最优值,具体见代码,复杂度不大会算。

    注意:

      开始我认为自己是水过的,因为我看到n是100的最大值,然后考虑到边是10000的最大值,便有了10000*10000的复杂度, 后来仔细想想,题目给的边数m<5000,那么自然有5000*5000不会超时。

      另外,我开始有个想法是: 每枚举边ei,做完一遍生成树后,删除边ei,维护相关信息,然后再做生成树,这样就是从ei+1开始了,复杂的会大大降低,但是我还是想不出来如何删边且维护相关信息。

    代码:

    poj3522
     1 /*3522    Accepted    320K    63MS    C++    1681B    2012-04-20 11:09:28*/
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <vector>
     8 using namespace std;
     9 
    10 #define mpair make_pair
    11 #define pii pair<int,int>
    12 #define MM(a,b) memset(a,b,sizeof(a));
    13 typedef long long lld;
    14 typedef unsigned long long u64;
    15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
    16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
    17 #define maxn
    18 
    19 int n,m;
    20 struct Edge{
    21     int u,v,w;
    22     void read(){
    23         scanf("%d%d%d", &u, &v, &w);
    24     }
    25     bool operator<(Edge b)const{
    26         return w<b.w;
    27     }
    28 } edge[10050];
    29 
    30 const int inf= 200000000;
    31 int fa[110];
    32 int find(int x){
    33     if( x==fa[x] ) return x;
    34     else return fa[x]= find( fa[x] );
    35 }
    36 int solve(){
    37     int ans= inf;
    38     for(int k=1;k<=m;++k){
    39         for(int i=1;i<=n;++i) fa[i]= i;
    40         int mmin= inf, mmax= -inf;
    41         int cnt= 0;
    42 
    43         for(int i=k;i<=m;++i){
    44             int x= edge[i].u, y= edge[i].v;
    45             int fx= find(x), fy= find(y);
    46             if( fx!=fy ){
    47                 fa[fy]= fx;
    48                 up_min( mmin, edge[i].w );
    49                 up_max( mmax, edge[i].w );
    50                 if( ++cnt == n-1 ) break;
    51                 if( mmax-mmin >= ans ) break; ///
    52             }
    53         }
    54         if( cnt == n-1 ) up_min( ans, mmax-mmin );
    55     }
    56     return ans;
    57 }
    58 
    59 int main()
    60 {
    61     while( cin>>n>>m, (n+m) ){
    62         for(int i=1;i<=m;++i)
    63             edge[i].read();
    64         sort( edge+1, edge+1+m );
    65 
    66         int ans= solve();
    67         if( ans!=inf ) cout<< ans <<endl;
    68         else puts("-1");
    69     }
    70 }
    一毛原创作品,转载请注明出处。
  • 相关阅读:
    Atomikos 中文说明文档(周枫翻译) 东师理想
    flex手机项目嵌套html页面和html页面播放声音文件 东师理想
    sql server 创建 ASPState 数据库方法 东师理想
    Android中文API(博客翻译版转载) 东师理想
    sql server导入excel和多表关联更新 东师理想
    关于CSS样式zindex在firefox和平板电脑中的问题 东师理想
    使用Flash builder 4.6创建Flex手机项目读取XML文件方法 东师理想
    android动画切换(滑屏效果)实例 东师理想
    一个障碍,就是一个超越自我的契机(转载)
    多去阅读思维训练类的书籍(转载)
  • 原文地址:https://www.cnblogs.com/yimao/p/2459060.html
Copyright © 2011-2022 走看看