hdu4756 Install Air Conditioning(MST + 树形DP)

题目请戳这里

题目大意:给n个点,现在要使这n个点连通,并且要求代价最小。现在有2个点之间不能直接连通(除了第一个点),求最小代价。

题目分析:跟这题一样样的,唉,又是原题。。先求mst,然后枚举边,对于生成树上的边替换,用树形dp O(N^2)求出每条生成树边的最小替代边。然后替换后的最大值。

详情请见代码:

 

#include <iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

#include<cstdlib>

#include<cctype>

#include<map>

#include<vector>

#include<set>

#include<queue>

#include<string>

using namespace std;

const int N = 1005;

const int M = 3000005;

const int inf = 0x3f3f3f3f;

const double eps = 1e-6;

const double PI = acos(-1.0);

typedef __int64 ll;

double dis[N][N];

double dp[N][N];

bool used[N][N];

bool flag[N];

double lowcost[N];

int pre[N],head[N];

struct node

{

    int x,y;

}pt[N];

struct nd

{

    int to,next;

}e_mst[M];

int n,m,num;

double B;

void build(int s,int e)

{

    e_mst[num].to = e;

    e_mst[num].next = head[s];

    head[s] = num ++;

}

double getdis(int x1,int y1,int x2,int y2)

{

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

}

void prim()

{

    B = 0;

    int i,j;

    memset(flag,false,sizeof(flag));

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

    {

        lowcost[i] = dis[1][i];

        pre[i] = 1;

    }

    flag[1] = true;

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

    {

        double Min = 100000000.0;

        int v;

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

        {

            if(flag[j] == false && lowcost[j] < Min)

            {

                Min = lowcost[j];

                v = j;

            }

        }

        B += Min;

        used[pre[v]][v] = used[v][pre[v]] = true;

        build(v,pre[v]);

        build(pre[v],v);

        flag[v] = true;

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

        {

            if(flag[j] == false && lowcost[j] > dis[v][j])

            {

                lowcost[j] = dis[v][j];

                pre[j] = v;

            }

        }

    }

}

double dfs(int cur,int u,int fa)

{

    double ret = inf;

    for(int i = head[u];~i;i = e_mst[i].next)

    {

        if(e_mst[i].to == fa)

            continue;

        double tmp = dfs(cur,e_mst[i].to,u);

        ret = min(tmp,ret);

        dp[u][e_mst[i].to] = dp[e_mst[i].to][u] = min(tmp,dp[u][e_mst[i].to]);

    }

    if(cur != fa)

        ret = min(ret,dis[cur][u]);

    return ret;

}

int main()

{

    int t,i,j;

    scanf("%d",&t);

    while(t --)

    {

        scanf("%d%d",&n,&m);

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

            scanf("%d%d",&pt[i].x,&pt[i].y);

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

            for(j = 1;j <= i;j ++)

            {

                dp[i][j] = dp[j][i] = inf;

                if(i == j)

                    dis[i][j] = 0;

                else

                    dis[i][j] = dis[j][i] = getdis(pt[i].x,pt[i].y,pt[j].x,pt[j].y);

            }

        memset(used,false,sizeof(used));

        memset(head,-1,sizeof(head));

        num = 0;

        prim();

        double ans = B;

        for(i = 0;i < n;i ++)

            dfs(i,i,-1);

        for(i = 2;i <= n;i ++)

        {

            for(j = 2;j < i;j ++)

            {

                if(used[i][j] == true)

                {

                    ans = max(ans,B-dis[i][j]+dp[i][j]);

                }

            }

        }

        printf("%.2lf\n",ans*m);

    }

    return 0;

}

//718MS	17100K


 


 

你可能感兴趣的:(Condition)