HDU
来源:互联网 发布:淘宝客怎么拉人进群 编辑:程序博客网 时间:2024/06/01 16:35
题目网址:点击打开链接
这个wa了一天的题,,,总算是知道错哪了;
这个题目的要求是找两点之间建立一条边,然后这两个点的人口数为A,B为除去这两个点之间的距离,所有点相连通的其他路的总长;
因而转化为一个次小生成树的问题,先生成一个最小生成树,然后开始删边,删一条边之后会发现,分成的两个集合中任意两个点相连,所有的点就又是相互连通的了;
这个题目由于A/B的值未知,所以每两个点都需要考虑进去,想要在任意两个点之间建路,然后B希望最小,就是从两个点之间相连的路上寻找一个最长的边删掉,然后再将这两个点连通起来,又是一个连通图;
所以这个问题的核心就在于,寻找每两个点连接路上的最大路长;
例如1——————2————3——4
|
6
如果希望在1-6之间建路的话,应该删掉的边是1-2他最长,然后连接1-6,又是一个树;
行了该上代码了
#include <iostream>#include<cstring>#include<string>#include<algorithm>#include<vector>#include<cmath>#include<cstdio>using namespace std;const int maxn=1000+5;struct node{ int x,y;};struct ege{ int e,v; double w; ege(int ee=0,int vv=0,double ww=0) { e=ee;v=vv;w=ww; } bool operator<(const ege& s)const { return w<s.w; }};ege eg[maxn*maxn+5];int p[maxn];int pro[maxn];int n,V,t;node s[maxn];double dis(int x,int y){ return sqrt((double)(s[x].x-s[y].x)*(s[x].x-s[y].x)*1.0+(s[x].y-s[y].y)*(s[x].y-s[y].y)*1.0);}void inint(int n){ for(int i=0;i<=n;i++) pro[i]=i;}int find(int x){ if(x==pro[x]) return x; else return pro[x]=find(pro[x]);}void uion(int x,int y){ int xx=find(x); int yy=find(y); if(xx==yy) return ; else pro[xx]=yy;}int same(int x,int y){ if(find(x)==find(y)) return 1; else return 0;}vector <ege> e2[maxn];double kur(){ inint(n); double res=0; int numm=0; sort(eg,eg+V); for(int i=0;i<V;i++) { ege ee=eg[i]; if(!same(ee.e,ee.v)) { numm++; uion(ee.e,ee.v); res+=ee.w; e2[ee.e].push_back(ee); e2[ee.v].push_back(ege(ee.v,ee.e,ee.w));//这里之前不小心写错了 if(numm==n-1) break; } } return res;}int cur[maxn];int vis[maxn];double e[maxn][maxn];int num;void dfs(int c){ vis[c]=1; cur[num]=c; num++; for(int i=0;i<e2[c].size();i++) { int v=e2[c][i].v; double w=e2[c][i].w; if(!vis[v]) {//cout<<w<<endl; //vis[v]=1; for(int j=0;j<num;j++) { e[v][cur[j]]=max(w,e[cur[j]][c]); e[cur[j]][v]=max(w,e[cur[j]][c]); //这就是我说的那个核心部分了, // 要注意的是,1-6 之间的最大距离应该在1-3和3-6之间产生,所以是e[6][1]=max(e[3][6]],e[1][3]); } dfs(v); } }}int main(){ cin>>t; while(t--) { cin>>n; for(int i=0;i<n;i++) { cin>>s[i].x>>s[i].y>>p[i]; } V=0; memset(eg,0,sizeof(eg)); for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) { eg[V]=ege{i,j,dis(i,j)}; // cout<<dis(i,j)<<endl;; V++; } for(int i=0;i<n;i++) e2[i].clear(); double res= kur(); // cout<<res<<endl; num = 0; memset(vis,0,sizeof(vis)); memset(e,0,sizeof(e)); memset(cur,0,sizeof(cur)); dfs(0); double maxx = 0; for(int i = 0;i < n; i++) for(int j = i + 1;j < n; j++) { //cout<<e[i][j]<<" "; //cout<<" p="<<p[i]+p[j]<<endl; double ab = (double)(p[i]+p[j])/(res-e[i][j]); if(ab>maxx) maxx=ab; //cout<<maxx<<endl; } printf("%.2f\n",maxx); } // cout << "Hello world!" << endl; return 0;}
总算是不在wa了,很多东西不要简单的以为自己会了,真让你自己动手的时候才显示出真章,年轻人好好努力吧,要知道,下一个最小生成树,你可能还是不会;
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- logstash kafka多台机器取数据,只有一个实例消费
- MPLS VPN知识
- Java面向对象3
- 初学java--数据类型介绍
- eclipse安装、JDK安装、环境变量配置
- HDU
- Leetcode204.Count Primes
- Android_Android与Web端的数据交互
- A very hard mathematic problem HDU
- 微信小程序开发笔记(2017.07.27)
- 数据结构学习之图的深度优先遍历和广度优先遍历
- 【课程总结】FDU微电子科学与工程系大一专业课总结
- #UVA 540 Team Queue (STL map+queue)
- Fortran之open,write,read,inquire,Namelist 使用