• HDU4081 Qin Shi Huang's National Road System【prim最小生成树+枚举】


    先求出最小生成树,然后枚举树上的边,对于每条边“分别”找出这条割边形成的两个块中点权最大的两个

    1.因为结果是A/B。A的变化会引起B的变化,两个制约。无法直接贪心出最大的A/B。故要通过枚举

    2.无论magic road要加在哪里。加的边是否是最小生成树上的边,都会产生环,我们都要选择一条边删掉

    注意删掉的边必须是树的环上的边。为了使结果最大。即找出最大的边

    3.能够枚举两点。找出边,也能够枚举边,找出点,我是用后者。感觉比較easy写也好理解

    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <cstring>
    #include <cmath>
    using namespace std;
    const int INF=(1<<31)-1;
    int num;
    bool visit[1111];
    struct city{int x,y,popu;}point[1111];
    vector<int>G[1111];
    double getdis(city& a,city& b)
    {
    	double dx=a.x-b.x;
    	double dy=a.y-b.y;
    	return sqrt(dx*dx+dy*dy);
    }
    double dis[1111][1111];
    double prim()
    {
        double sum=0;
    	double dist[1111];
    	fill(dist,dist+1111,INF*1.0);
    	double minedge=INF;
    	int now=1,min_p;
    	int pre[1111];
    	memset(pre,0,sizeof(pre));
    	dist[now]=0;
    	visit[1]=true;
    	for(int t=1;t<num;t++)
    	{
    		for(int i=1;i<=num;i++)
    		{
    			if(i!=now && !visit[i] &&dist[i]>dis[now][i])
    			{
    				pre[i]=now;
    				dist[i]=dis[now][i];
    			}
    		}
    		minedge=INF;
    		for(int i=1;i<=num;i++)
    		{
    			if(!visit[i]&&minedge>dist[i])
    			{
    				minedge=dist[i];
    				min_p=i;
    			}
    		}
    		G[pre[min_p]].push_back(min_p);
    		G[min_p].push_back(pre[min_p]);
    		sum+=dis[min_p][pre[min_p]];
    		now=min_p;
    		visit[now]=true;
    	}
    	return sum;
    }
    int dfs(int v,int fa)
    {
    	int maxn=point[v].popu;
    	for(int j=0;j<G[v].size();j++)
    	{
    		if(G[v][j]!=fa)
    		{
    			maxn=max(maxn,dfs(G[v][j],v));
    		}
    	}
    	return maxn;
    }
    int main()
    {
    	#ifndef ONLINE_JUDGE
    		freopen("G:/1.txt","r",stdin);
    		freopen("G:/2.txt","w",stdout);
    	#endif
    	int T;
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d",&num);
    		for(int i=1;i<=num;i++)
    		{
    			scanf("%d%d%d",&point[i].x,&point[i].y,&point[i].popu);
    		}
    		for(int i=1;i<=num;i++)
    		{
    			for(int j=1;j<=num;j++)
    			{
    				dis[i][j]=getdis(point[i],point[j]);
    			}
    		}
    		double sum=prim();
    		double ans=0;
    		for(int i=1;i<=num;i++)
    		{
    			for(int j=0;j<G[i].size();j++)
    			{
    				int t1=dfs(i,G[i][j]);
    				int t2=dfs(G[i][j],i);
    				ans=max(ans,(t1+t2)*1.0/(sum-dis[i][G[i][j]]));
    			}
    		}
    		//ans+=(1e-8);
    		printf("%.2f
    ",ans);
    		for(int i=1;i<=num;i++)
    		{
    			G[i].clear();
    		}
    		memset(point,0,sizeof(city)*(num+1));
    		memset(visit,0,sizeof(bool)*(num+1));
    	}
    }
    


     

  • 相关阅读:
    【未完待续】MVC 之HTML辅助方法
    【部分】ASP.NET MVC5
    【总结】Github通过Git Bash上传文件到仓库
    【总结】委托和匿名委托的比较
    函数进化到Lambda表达式的三过程
    C# 常用linq、lambda表达式整理 【转】
    Lambda表达式用在什么地方?如何使用?
    【错误】fatal: destination path already exists and is not an empty directory. 错误及解决办法
    GIT更换连接方式
    Github中添加SSH key
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/6770511.html
Copyright © 2020-2023  润新知