zoukankan      html  css  js  c++  java
  • poj 2728 最优比率树(最小生成树问题)

    好蛋疼啊,由于double 不能用memset,害的我调了一个多小时才发现。由于用二分搜索,时间有点大

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #define maxn 1005
    using namespace std;
    
    const int INF = 0x3f3f3f;
    
    struct node{
    	int x,y,z;
    }Node[maxn];
    double d[maxn];
    double G[maxn][maxn];
    double cost[maxn][maxn];
    double benefit[maxn][maxn]; 
    int  n;
    double mid,ans;
    
    void calculate(int i,int j){
    	cost[i][j] = cost[j][i] = abs(Node[i].z - Node[j].z);
    	int x1=Node[i].x, y1=Node[i].y;
    	int x2=Node[j].x, y2=Node[j].y;
    	benefit[i][j] = benefit[j][i] = sqrt(1.0*(x1-x2)*(x1-x2) + 1.0*(y1-y2)*(y1-y2));
    }
    
    void makemap(){
    	for(int i=1;i<=n;i++)
    	 for(int j=i+1;j<=n;j++){
      		G[i][j] = G[j][i] = cost[i][j] - mid * benefit[i][j]; 
      	}
      	
      	return;
    }
    void prim(){
    	bool vis[maxn];
    	double mindist;
    	double lowdist[maxn];
    	memset(vis,0,sizeof(vis));
    	for(int i=1;i<=n;i++) lowdist[i] = INF;
    	int point;
    	ans = 0.0;
    	int s=1;
    	int num=1;
    	while(true){
    		if(num == n) break;
    		vis[s] = true;
    		mindist = INF;
    		for(int i=1;i<=n;i++){
    			if(!vis[i] && lowdist[i] > G[s][i]){
       				lowdist[i] = G[s][i];
    			}
    			if(!vis[i] && lowdist[i] < mindist){
    				mindist = lowdist[i];  
    				point = i;
    			}
    		} 
    		s = point;
    		ans += mindist;  
    		num++;
    	}
    	return;
    }
    int main()
    {
    	//if(freopen("input.txt","r",stdin)== NULL)  {printf("Error\n"); exit(0);}
    
    	while(cin>>n && n){
    		for(int i=1;i<=n;i++){
    			cin>>Node[i].x>>Node[i].y>>Node[i].z;
    		}
    		for(int i=1;i<=n;i++)
    		     for(int j=i+1;j<=n;j++){
      			    calculate(i,j);
      		     }
    		double R=10000000,L=0.0;
    		while( (R-L)>1e-6 ){
    		   mid = (R+L)/2;	
    	       for(int i=1;i<=n;i++)
    	          for(int j=1;j<=n;j++){
              		G[i][j] = INF;
              	}
    		   makemap();
      		   prim();
    		   if(ans >= 0)  L = mid; 
    		   else          R = mid; 
    		   
    		}
    		printf("%.3lf\n",L);
    	}
    	return 0;
    }
    

      还是迭代好上面的用时2500多MS,而这个只要297MS,空间复杂度是降不下来了。

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #define maxn 1005
    using namespace std;
    
    const int INF = 0x3f3f3f;
    
    struct node{
    	int x,y,z;
    }Node[maxn];
    double d[maxn];
    double G[maxn][maxn];
    double cost[maxn][maxn];
    double benefit[maxn][maxn]; 
    int  n;
    double mid,ans;
    
    void calculate(int i,int j){
    	cost[i][j] = cost[j][i] = abs(Node[i].z - Node[j].z);
    	int x1=Node[i].x, y1=Node[i].y;
    	int x2=Node[j].x, y2=Node[j].y;
    	benefit[i][j] = benefit[j][i] = sqrt(1.0*(x1-x2)*(x1-x2) + 1.0*(y1-y2)*(y1-y2));
    }
    
    void makemap(){
    	for(int i=1;i<=n;i++)
    	 for(int j=i+1;j<=n;j++){
      		G[i][j] = G[j][i] = cost[i][j] - mid * benefit[i][j]; 
      	}
      	
      	return;
    }
    void prim(){
    	bool vis[maxn];
    	double mindist;
    	struct low{
    		double lowdist;
    		int s;
    	}L[maxn]; 
    	memset(vis,0,sizeof(vis));
    	for(int i=1;i<=n;i++) L[i].lowdist = INF;
    	int point;
    	ans = 0.0;
    	int s=1;
    	int num=1;
    	double suma = 0.0,sumb = 0.0;
    	while(true){
    		if(num == n) break;
    		vis[s] = true;
    		mindist = INF;
    		for(int i=1;i<=n;i++){
    			if(!vis[i] && L[i].lowdist > G[s][i]){
       				L[i].lowdist = G[s][i];
       				L[i].s = s;
    			}
    			if(!vis[i] && L[i].lowdist < mindist){
    				mindist = L[i].lowdist;  
    				point = i;
    			}
    		} 
    		int a = L[point].s; 
    		suma += cost[a][point];
    		sumb += benefit[a][point];
    		
    		s = point;
    		num++;
    	}
    	ans = suma/sumb;
    	return;
    }
    int main()
    {
    	//if(freopen("input.txt","r",stdin)== NULL)  {printf("Error\n"); exit(0);}
    
    	while(cin>>n && n){
    		for(int i=1;i<=n;i++){
    			cin>>Node[i].x>>Node[i].y>>Node[i].z;
    		}
    		for(int i=1;i<=n;i++)
    		     for(int j=i+1;j<=n;j++){
      			    calculate(i,j);
      		     }
      		mid = 0.5;     
    		while( true){
    		   for(int i=1;i<=n;i++)
    	          for(int j=1;j<=n;j++){
              		G[i][j] = INF;
               }
    		   makemap();
      		   prim();
      		   
    		   if(abs(ans -mid) < 1e-6)  break;
       		   else           mid = ans; 
    		}
    		printf("%.3lf\n",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    在 django 中使用 mako or jinja2 (精简版) Python,Django language ITeye论坛
    Python发送WEB请求,并对WEB内容进行解析 lpxuan151009的专栏 博客频道 CSDN.NET
    egg hurt for django native template engine
    Java内部类与相关的设计模式(一)
    struts2官方入门案列curd 编辑
    中文标点符号unicode码
    浏览器与服务器连接
    为什么ListView.setOnItemClickListener、setOnCreateContextMenuListener会无效为什么ListView.setOnItemClickListen
    domino批量替换邮件模板
    ubuntu12.04上安装flashcahce
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3093267.html
Copyright © 2011-2022 走看看