HDOJ 4081
来源:互联网 发布:微信钱包表结构 mysql 编辑:程序博客网 时间:2024/04/25 14:16
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081
-————————————————————————————————————————————————
题目关键字: memset 、 prim
————————————————————————————————————————————————
题目描述:
无向完全图,有n个点,每个点有个点权。作一生成树,生成树上的一个边的边权可以忽略,若被忽略边权的边的两个端点的点权和为A,生成树剩余边的边权和为B,求一生成树使 A/B 最大,打印这个最大的比值。
————————————————————————————————————————————————
题目思路;
先求作一最小生成树。再扫描各边,若边在最小生成树中,则直接减掉这个边即可。若边不在最小生成树中,则减去加上该边构成的环中边权最大的。
在用prim求作最小生成树的过程中,用 dp[i][j]维护一个从i到j的最大边权值 :
dp[u][j] = dp[j][u] = max(dp[j][k],min) (**)
u是新加入的节点,k是u的前继。min是新加入的边。
所以不需要分类讨论了,当某个边 i j 属于最小生成树时,由于 dp[i][i]为0,所以dp[i][j]自然为 i与j的距离。
—————————————————————————————————————————————————
题目细节:
1、用prim算法较好,这样可以及时维护dp。(第一次写prim,莫敲。。再次感谢某位同学)
2、稠密图还是用邻接矩阵更省事儿。
——————————————————————————————————————————————————
源代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<math.h>using namespace std;#define MAX 2100000000#define maxn 1010#define max(a,b) ((a)<(b)?(b):(a))double edge[maxn][maxn];double p[maxn];double x[maxn];double y[maxn];double dis[maxn];int vis[maxn];int pre[maxn];double dp[maxn][maxn];int n = 0;double sum = 0;double d(double x1,double x2,double y1,double y2){ return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}void prim(){ int i = 0,j = 0; memset(vis,0,sizeof(vis)); sum = 0; for (int i=1;i<=n;i++) { pre[i]=i; dis[i]=MAX; } dis[1]=0; memset(dp,0,sizeof(dp));int u;for (i = 1;i<=n;i++){ doublemin = MAX;for (j = 1;j<=n;j++) if (!vis[j] && dis[j]<min) { min = dis[j]; u = j; }vis[u]=1;sum += min;int k = pre[u];for (j = 1;j<=n;j++) if (u!=j && vis[j])dp[u][j] = dp[j][u] = max(dp[j][k],min);for (j = 1;j<=n;j++) if (!vis[j] && edge[u][j]<dis[j]) { dis[j] = edge[u][j]; pre[j] = u; }}}int main(){ int t = 0; int i = 0,j = 0; double ans; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i = 1;i<=n;i++) { scanf("%lf%lf%lf",&x[i],&y[i],&p[i]); vis[i] = 0; for(j = 1;j<i;j++) { edge[i][j] = edge[j][i] = d(x[i],x[j],y[i],y[j]); } } prim(); ans = -MAX; for(i = 1;i<=n;i++) for(j = 1;j<i;j++) ans = max(ans,(p[i]+p[j])/(sum-dp[i][j])); printf("%.2lf\n",ans); } return 0;}
- HDOJ 4081
- hdoj 4081
- HDOJ
- hdoj
- hdoj
- HDOJ
- hdoj 1568 && hdoj 5344 && hdoj 5444
- HDOJ 4081: Qin Shi Huang's National Road System
- HDOJ 4081 Qin Shi Huang's National Road System
- HDOJ 2176
- Hdoj--1272
- hdoj 1003
- hdoj 1005
- hdoj 1030
- hdoj 2154
- hdoj 2100
- HDOJ 1106
- hdoj 1257
- iphone4开发基础教程的技术点总结2
- 杭电ACM 2018 母牛的故事
- Android 如何建立AIDL
- 为什么会出现子站点的CrawlDatum中的ifStart和finished字段与父站点相同?
- PE文件格式
- HDOJ 4081
- HDU 1211 RSA 逆元 快速模取幂
- 高通Android智能平台开发总结
- 正規表現の利用方法
- Oracle BAM的Drill Down实现
- Android Building System 分析(转)
- 百思买裁员2400人 电器零售巨头未来依旧迷茫
- linux命令行+SHELL编程学习(1)
- Android编译过程详解(一)