zoukankan      html  css  js  c++  java
  • hdoj 4081 Qin Shi Huang's National Road System

    http://acm.hdu.edu.cn/showproblem.php?pid=4081

    解题报告:

    先求最小生成树,并把这棵树记录下来,用low,和pre数组

    然后dp数组表示最大边,这个信息可以在求prim的时候得到。

    然后不断枚举任意两点修魔法路。那么这条路可能在最小生成树上,或者不在。

    如果不在则替换到这两点之间的在mst上的最长路。dp数组

    如果在咋直接替换到mst上的路 也是dp数组

    View Code
    #include<iostream>
    #include<string.h>
    #include<stdio.h>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn 1110
    #define inf  ~0U>>1
    double map[maxn][maxn];
    double people[maxn];
    double low[maxn];
    double max(double a,double b)
    {
        return a>b?a:b;
    }
    struct node0
    {
        double x;
        double y;
    }node[maxn];
    double dp[maxn][maxn];
    int n;
    int visit[maxn];
    int pre[maxn];
    double sum;
    double len(double x1,double y1,double x2,double y2)
    {
        return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    }
    void init()
    {
        memset(people,0,sizeof(people));
        for(int i=0;i<=maxn;i++)
        for(int j=0;j<=maxn;j++)
        map[i][j]=inf;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        scanf("%lf%lf%lf",&node[i].x,&node[i].y,&people[i]);
    }
    
    void MAP()
    {
           for(int i=1;i<n;i++)
            {
                for(int j=i+1;j<=n;j++)
                {
                    map[i][j]=map[j][i]=len(node[i].x,node[i].y,node[j].x,node[j].y);
                }
            }
    }
    
    double prim()
    {
        double temp;
        int id;
        double ans=0;
        memset(visit,0,sizeof(visit));
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)pre[i]=1;
        for(int i=1;i<=maxn;i++)low[i]=inf;
        visit[1]=1;
        for(int i=2;i<=n;i++)
            low[i]=map[1][i];
        for(int i=2;i<=n;i++)
        {
        temp=inf;
        for(int j=1;j<=n;j++)
            if(!visit[j]&&low[j]<temp)
        temp=low[j],id=j;
        ans+=temp,visit[id]=1;
        for(int j=1;j<=n;j++)
        if(visit[j]&&id!=j)
        dp[id][j]=dp[j][id]=max(dp[pre[id]][j],temp);
    
        for(int j=1;j<=n;j++)
            if(low[j]>map[id][j]&&!visit[j])
                low[j]=map[id][j],pre[j]=id;
        }
        return ans;
    }
    double  solve()
    {
        double  temp=0.0;
        double ans=0.0;
        for(int i=1;i<n;i++)
        for(int j=i+1;j<=n;j++)
        {
           temp=(people[i]+people[j])/(sum-dp[i][j]);
           ans=max(temp,ans);
        }
        return ans;
    }
    int main()
    {
        int test;
        for(cin>>test;test;test--)
        {
            init();
            MAP();
            sum=prim();
            printf("%.2f\n",solve());
        }
        return 0;
    }
  • 相关阅读:
    百度面试题
    京东2014年招聘会成都站笔试经历
    把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,不能申请额外的空间
    POJ 2234 Matches Game
    POJ 3903 Stock Exchange
    POJ 2853 Sequence Sum Possibilities
    POJ 3519 Minimal Backgammon
    POJ 2096 Collecting Bugs
    POJ 3071 Football
    HDU 1175 连连看
  • 原文地址:https://www.cnblogs.com/cs1003/p/2738000.html
Copyright © 2011-2022 走看看