uva 1494 Qin Shi Huang's National Road System

来源:互联网 发布:java 指定jdk版本运行 编辑:程序博客网 时间:2024/06/05 16:35

这题和求次小生成树的思路有点像。

首先求出最小生成树,在此过程中,我们用maxcost[a][b]维护在MST中a,b之间的最大边权值。

状态转移方程: maxcost[a][b] = max(maxcost[pre[a]][b] , dis[a]) pre[a]是a的前驱节点,dis[a]是到a的最短路。

然后我们在再枚举每一条边,每次用当前枚举的边置换maxcost[a][b],然后计算并更新结果。

#include <iostream>#include<cmath>#include<stdio.h>#include<cstring>#define maxn 1010#define INF 10000000using namespace std;int t,n,cnt;struct Node{    double x,y;    int peo;};Node node[maxn];struct Edge{    int from,to,next,mst;    double dist;};Edge e[maxn * maxn];int head[maxn];int vis[maxn];int mst[maxn][maxn];double ans,result;double maxcost[maxn][maxn];double dis[maxn];int pre[maxn];double mini;void add_edge(int a,int b){    double tmp = sqrt((node[a].x - node[b].x)*(node[a].x - node[b].x) + (node[a].y - node[b].y)*(node[a].y - node[b].y));    e[cnt].from = a;    e[cnt].to = b;    e[cnt].dist = tmp;    e[cnt].next = head[a];    head[a] = cnt;    cnt++;}void init(){    cnt = 0;    ans = 0;    result = 0;    memset(head,-1,sizeof head);    memset(mst,0,sizeof mst);    memset(maxcost,0,sizeof maxcost);}bool prim(){    int k;    memset(vis,0,sizeof vis);    for(int i = 1;i <= n;i++)  dis[i] = INF;    for(int i = head[1];i != -1;i = e[i].next)    {        int cur = e[i].to;        dis[cur] = min(e[i].dist,dis[cur]);        pre[cur] = 1;    }    vis[1] = 1;    dis[1] = 0;    for(int j = 1;j < n;j++)    {        mini = INF;        for(int i = 1;i <= n;i++)        {            if(!vis[i] && dis[i] < mini)            {                mini = dis[i];                k = i;            }        }        if(mini == INF) return false;        vis[k] = 1;        mst[pre[k]][k] = 1;        ans+=dis[k];        for(int i = head[k];i !=-1;i=e[i].next)        {            int cur = e[i].to;            maxcost[k][cur] = maxcost[cur][k] = max(maxcost[pre[k]][cur],dis[k]);            if(!vis[cur] && e[i].dist < dis[cur])            {                pre[cur] = k;                dis[cur] = e[i].dist;            }        }    }    return true;}void work(){    for(int i = 1;i <= n;i++)    {        for(int j = head[i];j !=-1;j = e[j].next)        {            int from = i;            int to = e[j].to;            double tmp = maxcost[from][to];            tmp =ans - tmp;            double tmp1 = node[from].peo + node[to].peo;            tmp1/=tmp;            if(tmp1 > result) result = tmp1;        }    }}int main(){    scanf("%d",&t);    while(t--)    {       scanf("%d",&n);       init();       for(int i = 1;i <= n;i++)       {           scanf("%lf %lf %d",&node[i].x,&node[i].y,&node[i].peo);       }       for(int i = 1;i <= n;i++)           for(int j = i + 1;j <= n;j++)           {               add_edge(i,j);               add_edge(j,i);           }        prim();        work();        printf("%.2lf\n",result);    }    return 0;}


0 0
原创粉丝点击