• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            The Fourth Dimension Space

            枯葉北風(fēng)寒,忽然年以殘,念往昔,語默心酸。二十光陰無一物,韶光賤,寐難安; 不畏形影單,道途阻且慢,哪曲折,如渡飛湍。斬浪劈波酬壯志,同把酒,共言歡! -如夢令

            POJ 2728 Desert King(最優(yōu)比率生成樹) prim+二分

            北京賽區(qū)的經(jīng)典題目,最優(yōu)比率生成樹,傳說中樓哥1A的G題。。。
            什么是最優(yōu)比率生成樹呢?說白了很簡單,已知一個(gè)完全圖,每條邊有兩個(gè)參數(shù)(b和c),求一棵生成樹,使(∑xi×ci)/(∑xi×bi)最小,其中xi當(dāng)?shù)趇條邊包含在生成樹中時(shí)為1,否則為0。其實(shí)也可以看成一個(gè)0,1的整數(shù)規(guī)劃問題。
            我的做法是LRJ《算法藝術(shù)與信息學(xué)競賽》中介紹的二分,詳細(xì)的證明請看書,這里只是簡單的介紹一下核心的方法:
            1.首先找出這個(gè)比率的最小值和最大值 front,rear
            2.求mid=(front+reat)/2
            3.用 ci-mid*bi 重新構(gòu)圖
            4.求出新圖的最小生成樹權(quán)值之和
            5.如果權(quán)值等于0,mid就是我們要求的比率,結(jié)束。如果權(quán)值>0,front=mid,如果權(quán)值<0,rear=mid,跳回2繼續(xù)循環(huán)。


            不過這個(gè)算法對精度的要求比較高,我用0.001就錯(cuò)了,0.00001超時(shí),只有0.0001AC,汗
            另外時(shí)間效率也不高,3000MS的題,耗去了2500MS,看來這個(gè)算法還是有待改進(jìn)。
            下面是我的代碼:

            #include<iostream>
            #include
            <algorithm>
            #include
            <cstring>
            #include
            <cmath>
            using namespace std;
            #define MAX 1001
            #define INF 1000000000
            struct node
            {

                
            double x,y,h;
            }
            dot[MAX];


            inline 
            double dis(double x1,double y1,double x2,double y2)
            {

                
            return sqrt( (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1) );
            }



            double graph[MAX][MAX];

            inline 
            void creat(int n,double l)
            {
                
            int i,j;
                
            for(i=1;i<=n;i++)
                
            {

                    
            for(j=1;j<=n;j++)
                    
            {

                        graph[i][j]
            =fabs(dot[i].h-dot[j].h)-l*dis(dot[i].x,dot[i].y,dot[j].x,dot[j].y);
                    }

                }

            }


            inline 
            double prim(double graph[MAX][MAX],int n)
            {
                
            bool visit[MAX]={0};
                
            int mark;
                
            double dis[MAX];
                
            double ans=0;
                
            int i,j;
                visit[
            1]=true;
                
            for(i=1;i<=n;i++)
                    dis[i]
            =graph[1][i];
                
            for(i=1;i<n;i++)
                
            {

                    
            int minnum=INF;
                    
            for(j=1;j<=n;j++)
                    
            {

                        
            if(!visit[j]&&dis[j]<=minnum)
                        
            {
                            minnum
            =dis[j];
                            mark
            =j;
                        }

                    }

                    visit[mark]
            =true;
                    ans
            +=dis[mark];
                    
            for(j=1;j<=n;j++)
                    
            {
                        
            if(!visit[j]&&graph[mark][j]<dis[j])
                            dis[j]
            =graph[mark][j];
                    }


                }

                
            return ans;
            }



            int main()
            {

                
            int i,j;
                
            int n;
                
            double res;
                
            while(scanf("%d",&n))
                
            {

                    
            if(n==0)
                        
            break;
                    
            for(i=1;i<=n;i++)
                    
            {
                        scanf(
            "%lf%lf%lf",&dot[i].x,&dot[i].y,&dot[i].h);
                    }

                    
            double front,rear;
                    front
            =0;
                    rear
            =100;//這個(gè)地方有點(diǎn)懸。。。
                    double mid;
                    
            double pre=0.0;
                    
            while(front<=rear)
                    
            {

                        mid
            =(front+rear)/2;
                        creat(n,mid);
                        res
            =prim(graph,n);
                        
            if(fabs(res-pre)<=0.0005)
                            
            break;
                        
            else if(res>0.0005)
                            front
            =mid;
                        
            else
                            rear
            =mid;
                    }

                    printf(
            "%.3lf\n",mid);
                }

                
            return 0;
            }

            ———————————————————————傳說中的分割線————————————————————————————
            終于在今天下午 使用迭代法將此題優(yōu)化到282MS,呵呵 這名字讓我又想起了數(shù)值分析。。。
            #include<iostream>
            #include
            <algorithm>
            #include
            <cstring>
            #include
            <cmath>
            using namespace std;
            #define MAX 1001
            #define INF 1000000000
            struct node
            {
                
            double x,y,h;
            }
            dot[MAX];


            inline 
            double dis(double x1,double y1,double x2,double y2)
            {

                
            return sqrt( (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1) );
            }



            double graph[MAX][MAX];
            double c[MAX][MAX];
            double s[MAX][MAX];

            inline 
            void creatcs(int n)
            {
                
            int i,j;
                
            for(i=1;i<=n;i++)
                
            {
                    
            for(j=1;j<=n;j++)
                    
            {
                        c[i][j]
            =fabs(dot[i].h-dot[j].h);
                        s[i][j]
            =dis(dot[i].x,dot[i].y,dot[j].x,dot[j].y);
                    }

                }

            }



            inline 
            void creat(int n,double l)
            {
                
            int i,j;
                
            for(i=1;i<=n;i++)
                
            {

                    
            for(j=1;j<=n;j++)
                    
            {

                        graph[i][j]
            =c[i][j]-l*s[i][j];
                    }

                }

            }

            double sumc;
            double sums;

            inline 
            void prim(double graph[MAX][MAX],int n)
            {
                sumc
            =0;
                sums
            =0;
                
            bool visit[MAX]={0};
                
            int mark;
                
            int pre[MAX];
                
            double dis[MAX];
                
            int i,j;
                visit[
            1]=true;
                
            for(i=1;i<=n;i++)
                
            {
                    dis[i]
            =graph[1][i];
                    pre[i]
            =1;
                }

                
            for(i=1;i<n;i++)
                
            {

                    
            int minnum=INF;
                    
            for(j=1;j<=n;j++)
                    
            {

                        
            if(!visit[j]&&dis[j]<=minnum)
                        
            {
                            minnum
            =dis[j];
                            mark
            =j;
                        }

                    }

                    visit[mark]
            =true;
                    sumc
            +=c[pre[mark]][mark];
                    sums
            +=s[pre[mark]][mark];
                    
            for(j=1;j<=n;j++)
                    
            {
                        
            if(!visit[j]&&graph[mark][j]<dis[j])
                        
            {
                            dis[j]
            =graph[mark][j];
                            pre[j]
            =mark;
                        }

                    }


                }

            }



            int main()
            {

                
            int i,j;
                
            int n;
                
            while(scanf("%d",&n))
                
            {

                    
            if(n==0)
                        
            break;
                    
            for(i=1;i<=n;i++)
                    
            {
                        scanf(
            "%lf%lf%lf",&dot[i].x,&dot[i].y,&dot[i].h);
                    }

                    creatcs(n);
                    
            double prerate=30.0;
                    
            double rate=30.0;
                    
            while(true)
                    
            {
                        creat(n,rate);
                        prim(graph,n);
                        rate
            =sumc/sums;
                        
            if(fabs(rate-prerate)<0.001)
                            
            break;
                        prerate
            =rate;
                    }

                    printf(
            "%.3lf\n",rate);
                }

                
            return 0;
            }

            posted on 2009-09-04 23:53 abilitytao 閱讀(2816) 評論(4)  編輯 收藏 引用

            評論

            # re: POJ 2728 Desert King(最優(yōu)比率生成樹) prim+二分 2009-09-05 12:05 凡客誠品

            不錯(cuò)哦  回復(fù)  更多評論   

            # re: POJ 2728 Desert King(最優(yōu)比率生成樹) prim+二分 2009-09-08 14:58 戴爾電腦

            世界的發(fā)生的糾紛  回復(fù)  更多評論   

            # re: POJ 2728 Desert King(最優(yōu)比率生成樹) prim+二分 2009-09-09 01:26 abilitytao

            @戴爾電腦
            做廣告的不妨給我們團(tuán)隊(duì)贊助吧 呵呵 要寫也要寫點(diǎn)有意義的東西 否則刪除 警告!  回復(fù)  更多評論   

            # re: POJ 2728 Desert King(最優(yōu)比率生成樹) prim+二分 2009-09-09 22:29 Vincent

            樓哥1a...很正常- -  回復(fù)  更多評論   

            久久精品国产99国产精品导航| 欧美亚洲色综久久精品国产| 99久久免费国产精品热| 久久福利青草精品资源站免费| 久久国产精品久久国产精品| 国产高潮久久免费观看| 人妻少妇精品久久| 久久国产精品一国产精品金尊 | 亚洲国产精品人久久| 久久精品男人影院| 性欧美大战久久久久久久| 精品伊人久久大线蕉色首页| 精品久久久久久亚洲| 久久久免费观成人影院| 亚洲国产另类久久久精品| 国产日产久久高清欧美一区| 久久伊人色| 色综合久久最新中文字幕| 久久国产AVJUST麻豆| 精品久久国产一区二区三区香蕉| 人妻无码久久一区二区三区免费 | 精品久久久久成人码免费动漫 | av色综合久久天堂av色综合在| 色偷偷888欧美精品久久久| 精品久久久久久久国产潘金莲| 国产激情久久久久影院小草 | 久久99精品久久久久久不卡| 久久精品国产AV一区二区三区| 青青热久久国产久精品 | 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 无码八A片人妻少妇久久| 青青国产成人久久91网| 久久久国产乱子伦精品作者| 一本久久a久久精品vr综合| 模特私拍国产精品久久| 色婷婷久久综合中文久久一本| 国产午夜电影久久| 久久久久久免费一区二区三区| 韩国免费A级毛片久久| 亚洲AV日韩精品久久久久久| 久久AV高潮AV无码AV|