HDU 4081 最小生成树变形

来源:互联网 发布:大观园网络电视直播 编辑:程序博客网 时间:2024/06/17 06:27

这道题我一开始的想法就是对的,记录任意两点路径上的最大边权,然后枚举两点,找到A/B的最大值。

关键是这个记录真不好记录,想来想去没什么想法,代码能力还是太弱了,想到了先生成树再来记录什么的,

觉得复杂度好高,还是觉得PRIM在加边的过程中就直接记录了,想了很久,后来才想通,开一个一维数组记录

它的父节点再开一个二维数组记录DP[I][J],I->J的路径上的最大边权,每加入一点,就在已经VISIT的集合里算

出所有的与这点路径上的最大边权,其实每次只要比较一次就好了,这个点到其父亲节点的距离,父亲节点与其他点的长度

选一个最大的就好了,因为在这个点加入之前,其父亲节点必然已经更新过了!

代码还未写注释,下次吧。。

#include<stdio.h>#include<stdlib.h>#include<math.h>#include<iostream>#include<string.h>#include<algorithm>#include<queue>#include<vector>#include<map>#define inf 0x7fffffff#define eps 1e-8#define maxn 1100using namespace std;double graph[maxn][maxn];int pre[maxn];double dp[maxn][maxn];double dist[maxn];int vis[maxn];int n;double ans;struct point{    double x,y;    int peo;}p[maxn];struct edge{    int u,v;    double len;}a[maxn*maxn];double dis(double x1,double y1,double x2,double y2){    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}double Max(double a,double b){    return a>b?a:b;}double prim(){    int i,j,k;    double sum=0.0;    memset(vis,0,sizeof(vis));    for(i=1;i<=n;i++)    {        dist[i]=graph[1][i];        pre[i]=1;        dp[i][i]=0.0;    }    vis[1]=1;    for(i=2;i<=n;i++)    {        double t=inf*1.0;        for(j=1;j<=n;j++)        {            if(!vis[j]&&dist[j]<t)            {                t=dist[j];                k=j;            }        }        int fa=pre[k];        dp[fa][k]=dp[k][fa]=graph[fa][k];        sum+=t;        for(j=1;j<=n;j++)        {            if(vis[j])            {               dp[j][k]=dp[k][j]=Max(dp[j][fa],dp[fa][k]);            }        }        vis[k]=1;        for(j=1;j<=n;j++)        {            if(!vis[j]&&dist[j]>graph[k][j])            {              pre[j]=k;             dist[j]=graph[k][j];            }        }    }    return sum;}void solve(double res){    int i,j;    ans=0.0;    for(i=1;i<=n;i++)    {        for(j=i+1;j<=n;j++)        {            double mi=(p[i].peo+p[j].peo)*1.0/(res-dp[i][j]);            if(mi>ans)            ans=mi;        }    }}int main(){   //freopen("in.txt","r",stdin);   int t;   scanf("%d",&t);   while(t--)   {       int i,j;       memset(graph,0,sizeof(graph));       scanf("%d",&n);       for(i=1;i<=n;i++)       {           scanf("%lf%lf%d",&p[i].x,&p[i].y,&p[i].peo);       }       for(i=1;i<=n;i++)       {           for(j=i+1;j<=n;j++)           {               graph[i][j]=graph[j][i]=dis(p[i].x,p[i].y,p[j].x,p[j].y);               dp[i][j]=dp[j][i]=0;           }       }       double res=prim();       //printf("%.2lf\n",res);       solve(res);       printf("%.2lf\n",ans);   }   return 0;}


原创粉丝点击