HDU 4081 Qin Shi Huang's National Road System
来源:互联网 发布:c语言控制机械手 编辑:程序博客网 时间:2024/05/16 18:49
题目大意:
现有t个测例(t ≤ 10),每个测例都会给出n个点的坐标(2 < n ≤ 1,000),每个点的坐标信息形式诸如"X Y P",表示点的坐标为(X, Y),点权值为P,都为整型,其中0 ≤ X, Y ≤ 1,000,0 < P < 100,000,现要求n - 1条边将所有n个点都连通,并且将其中一条边的权值变为0,现要使变为0的边的两点的权值之和比上其它边权值之和最大,该如何构造这n - 1条以及如何挑选变为0的边才能是该比值最大,要求对于每个测例都输出该最大值,保留两位小数(边长即为两点的欧几里得距离)。
题目链接
注释代码:
/* * Problem ID : HDU 4081 Qin Shi Huang's National Road System * Author : Lirx.t.Una * Language : C++ * Run Time : 171 ms * Run Memory : 18200 KB */#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <queue>//思路://先求MST使得n个点连通且边数为n - 1,并且使得总边权尽可能小//这也使得点权比边权尽可能大//然后在挑选边变为0测试ratio的大小,但是最小生成树可能有多个//本来边(i, j)不在当前MST中,但是有可能在另一个MST中//因此需要通过max_seg[i][j]换边得到另一种最小生成树//但是g[i][j]并不一定等于max_seg[i][j],但是没有关系//因为即使替换了也要将其边权变为0,就相当于将两点合为一点,因此没有关系//因此最后逐个检查图中的每条边g[i][j],如果g[i][j]是当前MST中的点则非0边权为总边权减去g[i][j]//否则非0边权就是总边权减去max_seg[i][j]//最大点数#define MAXN 1000using namespace std;struct Point {//每个点的坐标以及点权值 int x, y; int w; friend istream & operator>>(istream &is, Point &p) { is >> p.x >> p.y >> p.w; return is; } int POW(int a) { return a * a; } double operator^(Point &oth) { return sqrt((double)( POW( x - oth.x ) + POW( y - oth.y ) )); }};struct Node {//Prim堆优化中的结点 int u; double d; Node(void) {} Node( int uu, double dd ) : u(uu), d(dd) {} bool operator<(const Node &oth) const { return d > oth.d; }};double max_seg[MAXN + 1][MAXN + 1];double g[MAXN + 1][MAXN + 1];double d[MAXN + 1];Point p[MAXN + 1];//表示每个点int pre[MAXN + 1];bool vis[MAXN + 1];bool mst[MAXN + 1][MAXN + 1];inline doublemax( double a, double b ) { return a > b ? a : b;}double//返回最小生成树的总边权prim(int n) { int i; int u, v; int nv; double ans; Node node; priority_queue<Node> heap; memset(vis, 0, sizeof(vis)); memset(mst, 0, sizeof(mst)); memset(max_seg, -1, sizeof(max_seg)); vis[1] = true; for ( i = 2; i <= n; i++ ) { d[i] = g[1][i]; pre[i] = 1; heap.push(Node( i, d[i] )); } ans = 0.0; nv = 1; while (true) {//完全图必定有解,无需判断 while (true) {//必定有解 node = heap.top(); heap.pop(); if ( !vis[ u = node.u ] ) { nv++; ans += node.d; mst[ pre[u] ][u] = true; mst[u][ pre[u] ] = true; for ( i = 1; i <= n; i++ ) if ( vis[i] ) { max_seg[i][u] = max( max_seg[i][ pre[u] ], node.d ); max_seg[u][i] = max_seg[i][u]; } vis[u] = true; break; } } if ( nv == n ) break; for ( v = 2; v <= n; v++ ) if ( !vis[v] && g[u][v] < d[v] ) { d[v] = g[u][v]; pre[v] = u; heap.push(Node( v, d[v] )); } } return ans;}intmain() { int t; int n; int i, j; double B;//MST边的总权值 double r;//最后的比例 scanf("%d", &t); while ( t-- ) { scanf("%d", &n); for ( i = 1; i <= n; i++ ) cin >> p[i]; for ( i = 1; i <= n; i++ ) for ( j = i + 1; j <= n; j++ ) { g[i][j] = p[i] ^ p[j]; g[j][i] = g[i][j]; } r = -1.0;//初始化为一个极小值 B = prim(n); for ( i = 1; i <= n; i++ ) for ( j = i + 1; j <= n; j++ ) if ( mst[i][j] )//MST中的边之间边为0试一下 r = max( r, ( p[i].w + p[j].w ) / ( B - g[i][j] ) ); else//非MST中的边g[i][j]替换max_seg[i][j]再变为0试一下 r = max( r, ( p[i].w + p[j].w ) / ( B - max_seg[i][j] ) ); printf("%.2lf\n", r); } return 0;}无注释代码:
#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <queue>#define MAXN 1000using namespace std;struct Point { int x, y; int w; friend istream & operator>>(istream &is, Point &p) { is >> p.x >> p.y >> p.w; return is; } int POW(int a) { return a * a; } double operator^(Point &oth) { return sqrt((double)( POW( x - oth.x ) + POW( y - oth.y ) )); }};struct Node { int u; double d; Node(void) {} Node( int uu, double dd ) : u(uu), d(dd) {} bool operator<(const Node &oth) const { return d > oth.d; }};double max_seg[MAXN + 1][MAXN + 1];double g[MAXN + 1][MAXN + 1];double d[MAXN + 1];Point p[MAXN + 1];int pre[MAXN + 1];bool vis[MAXN + 1];bool mst[MAXN + 1][MAXN + 1];inline doublemax( double a, double b ) { return a > b ? a : b;}doubleprim(int n) { int i; int u, v; int nv; double ans; Node node; priority_queue<Node> heap; memset(vis, 0, sizeof(vis)); memset(mst, 0, sizeof(mst)); memset(max_seg, -1, sizeof(max_seg)); vis[1] = true; for ( i = 2; i <= n; i++ ) { d[i] = g[1][i]; pre[i] = 1; heap.push(Node( i, d[i] )); } ans = 0.0; nv = 1; while (true) { while (true) { node = heap.top(); heap.pop(); if ( !vis[ u = node.u ] ) { nv++; ans += node.d; mst[ pre[u] ][u] = true; mst[u][ pre[u] ] = true; for ( i = 1; i <= n; i++ ) if ( vis[i] ) { max_seg[i][u] = max( max_seg[i][ pre[u] ], node.d ); max_seg[u][i] = max_seg[i][u]; } vis[u] = true; break; } } if ( nv == n ) break; for ( v = 2; v <= n; v++ ) if ( !vis[v] && g[u][v] < d[v] ) { d[v] = g[u][v]; pre[v] = u; heap.push(Node( v, d[v] )); } } return ans;}intmain() { int t; int n; int i, j; double B; double r; scanf("%d", &t); while ( t-- ) { scanf("%d", &n); for ( i = 1; i <= n; i++ ) cin >> p[i]; for ( i = 1; i <= n; i++ ) for ( j = i + 1; j <= n; j++ ) { g[i][j] = p[i] ^ p[j]; g[j][i] = g[i][j]; } r = -1.0; B = prim(n); for ( i = 1; i <= n; i++ ) for ( j = i + 1; j <= n; j++ ) if ( mst[i][j] ) r = max( r, ( p[i].w + p[j].w ) / ( B - g[i][j] ) ); else r = max( r, ( p[i].w + p[j].w ) / ( B - max_seg[i][j] ) ); printf("%.2lf\n", r); } return 0;}
0 0
- HDU 4081 Qin Shi Huang's National Road System
- hdu 4081 Qin Shi Huang's National Road System
- HDU 4081 Qin Shi Huang's National Road System
- hdu 4081 Qin Shi Huang's National Road System
- HDU 4081 Qin Shi Huang's National Road System
- HDU 4081 Qin Shi Huang's National Road System
- hdu-4081-Qin Shi Huang's National Road System
- HDU 4081 Qin Shi Huang's National Road System
- HDU 4081 Qin Shi Huang's National Road System
- hdu 4081 Qin Shi Huang's National Road System
- hdu 4081 Qin Shi Huang's National Road System
- HDU-4081-Qin Shi Huang's National Road System
- HDU 4081 Qin Shi Huang's National Road System
- hdu 4081 Qin Shi Huang's National Road System
- hdu 4081 Qin Shi Huang's National Road System
- [hdu-4081] Qin Shi Huang's National Road System题解
- 【HDU 4081】 Qin Shi Huang's National Road System
- hdu 4081 Qin Shi Huang's National Road System
- 华为机试 - 约瑟夫问题
- Palindrome Number
- 谷歌pb协议
- 在php中操作memcached缓存进行增删改查数据
- Container With Most Water
- HDU 4081 Qin Shi Huang's National Road System
- Nexus 5 Android L 使用感受,以及如何刷回 4.4 Kitkat
- 习题练手一
- httpclient 4.3.1 post get的工具类
- HDU 4892 状压dp
- HDU1498_50 years, 50 colors(二分图/最小点覆盖=最大匹配)
- HDU 1498 50 years, 50 colors(二分最大匹配之最小点覆盖)
- Ubuntu 12.04 LTS 64位 使用Drcom 不能联网的解决办法
- [笔记] 编译内核加载initrd找不到SCSI硬盘