zoukankan      html  css  js  c++  java
  • HDU4756+Prim

    题意简单:去掉最小生成树的某一条边并补上一条,求MaxVal

    思路:贪心(借鉴Yamidie的思路。。。)

    分别求出最小生成树和次最小生成树,再在这两棵树上求最小生成树

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<algorithm>
    #include<math.h>
    using namespace std;
    const int maxn = 1015;
    const int maxm = maxn*maxn;
    const int inf1 = 0x3f3f3f3f;
    const double inf2 = 9999999999;
    
    struct Point {
        double x,y;
    }pnt[ maxn ];
    struct Edge{
        int u,v;
        double val;
        int id;
    }edge[ maxn<<1 ];
    int cnt_edge;
    double mat[ maxn ][ maxn ];
    double dis[ maxn ];
    bool vis[ maxn ];
    int pre[ maxn ];
    
    double LenPrim1;
    double LenPrim2;
    
    int fa[ maxn ],rank[ maxn ];
    
    int find( int x ){
        if( x==fa[x] ) return x;
        else return fa[ x ] = find( fa[x] );
    }
    
    void init( int n ){
        for( int i=0;i<n;i++ ){
            fa[ i ] = i;
            rank[ i ] = 1;
        }
        return ;
    } 
     
    double dist( int i,int j ){
        return sqrt( (pnt[i].x-pnt[j].x)*(pnt[i].x-pnt[j].x)+(pnt[i].y-pnt[j].y)*(pnt[i].y-pnt[j].y) );
    } 
    
    int cmp( Edge a,Edge b ){
        return a.val<b.val;
    }    
    
    void GetMap( int n ){
        for( int i=0;i<n;i++ )
            for( int j=0;j<n;j++ ){
                mat[i][j] = dist( i,j );
                //printf("mat[%d][%d]=%.3lf
    ",i,j,mat[i][j]);
            }
        return ;
    }
    
    double prim( int n,int Belong ){
        for( int i=0;i<n;i++ ){
            dis[ i ] = mat[0][i];
            vis[ i ] = false;
            pre[ i ] = 0;
        }
        vis[0] = true;
        //if( Belong==2 ){
        //    for( int i=0;i<n;i++ )for( int j=0;j<n;j++ ) 
                //printf("mat[%d][%d]=%.3lf
    ",i,j,mat[i][j]);
        //}
        double ans = 0;
        for( int i=0;i<n;i++ ){
            int id = -1;
            double M = inf2;
            for( int j=0;j<n;j++ ){
                if( !vis[j] && M>dis[j] ){
                    M = dis[j];
                    id = j;
                }
            }
            if( id==-1 ) break;
            vis[ id ] = true;
            ans += M;
            edge[ cnt_edge ].u = pre[ id ];
            edge[ cnt_edge ].v = id;
            edge[ cnt_edge ].id = Belong;
            edge[ cnt_edge ].val = mat[ id ][ pre[id] ];
            //printf("u = %d,v = %d
    ",edge[cnt_edge].u,edge[cnt_edge].v);
            cnt_edge ++ ;
            for( int j=0;j<n;j++ ){
                if( !vis[j] && dis[j]>mat[id][j] ){
                    dis[j] = mat[id][j];
                    pre[ j ] = id;
                }
            }
        }
        return ans;
    }    
    
    void Deal( int n ){
        for( int i=0;i<cnt_edge;i++ ){
            mat[ edge[i].u ][ edge[i].v ] = inf2;
            mat[ edge[i].v ][ edge[i].u ] = inf2;
        }
    }
    
    double Kruskal( int n,int id ){
        double ans = 0;
        init( n );
        int cnt = 0;
        for( int i=0;i<cnt_edge;i++ ){
            if( i==id ) continue;
            int fx = find( edge[i].u );
            int fy = find( edge[i].v );
            if( fx!=fy ){
                if( rank[ fx ]<rank[ fy ] ){
                    rank[ fy ] += rank[ fx ];
                    fa[ fx ] = fy;
                }
                else {
                    rank[ fx ] += rank[ fy ];
                    fa[ fy ] = fx;
                }
                cnt ++ ;
                ans += edge[i].val;
                if( cnt==n-1 ) break;
            }
           }
           return ans;
    }
    
    int main(){
        int T;
        scanf("%d",&T);
        while( T-- ){
            int n;
            double k;
            scanf("%d%lf",&n,&k);
            for( int i=0;i<n;i++ )
                scanf("%lf%lf",&pnt[i].x,&pnt[i].y);
            GetMap( n );
            cnt_edge = 0;
            LenPrim1 = prim( n,1 );
            Deal( n );
            LenPrim2 = prim( n,2 );
            double ans = LenPrim1;
            double temp_ans = 0;
            sort( edge,edge+cnt_edge,cmp );
            //printf("cnt_edge = %d
    ",cnt_edge);
            for( int i=0;i<cnt_edge;i++ ){
                if( edge[i].id==1 && edge[i].u!=0 && edge[i].v!=0 ){
                    temp_ans = Kruskal( n,i );
                    if( temp_ans>ans )
                        ans = temp_ans;
                }
            }
            printf("%.2lf
    ",ans*k);
        }
        return 0;
    }
    


     

  • 相关阅读:
    bzoj 3527: [Zjoi2014]力
    bzoj 1797: [Ahoi2009]Mincut 最小割
    bzoj 1028: [JSOI2007]麻将
    bzoj 1019: [SHOI2008]汉诺塔
    bzoj 1023: [SHOI2008]cactus仙人掌图
    bzoj 3289: Mato的文件管理
    bzoj 4034: [HAOI2015]T2
    bzoj 1218: [HNOI2003]激光炸弹
    bzoj 2431: [HAOI2009]逆序对数列
    The full stack trace of the root cause is available in the Apache Tomcat/8.0.8 logs.
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3339393.html
Copyright © 2011-2022 走看看