LA 5717枚举+最小生成树回路性质

news/2024/7/7 22:31:41
  1 /*LA 5717
  2 《训练指南》P343
  3 最小生成树的回路性质
  4 在生成的最小生成树上,新增一条边e(u,v)
  5 若原图上u到v的路径的最大边大于e,则删除此边,加上e,否则不变。
  6 
  7 若原图上u到v的路径的最大边的产生:BFS/DFS都可 ,nm的复杂度,从每个点出发,找到每条边,更新最大即可
  8 */
  9 
 10 #include<iostream>
 11 #include<string.h>
 12 #include<stdio.h>
 13 #include<stdlib.h>
 14 #include<cmath>
 15 #include<algorithm>
 16 #include<queue>
 17 #include<stack>
 18 #include<set>
 19 #include<map>
 20 #define LL unsigned long long
 21 #define maxn 1010
 22 #define INF 99999
 23 using namespace std;
 24 
 25 double X[maxn];
 26 double Y[maxn];
 27 int Peo[maxn];
 28 int p[maxn];
 29 double L;//最小生成树总长度
 30 double MaxDis[maxn][maxn];
 31 int n,cnt;
 32 
 33 double nextnum()
 34 {
 35     double x;
 36     scanf("%lf",&x);
 37     return x;
 38 }
 39 int nextint()
 40 {
 41     int x;
 42     scanf("%d",&x);
 43     return x;
 44 }
 45 
 46 struct Edge
 47 {
 48     double u,v,dis;
 49     bool operator<(const Edge&x)const
 50     {
 51         return dis<x.dis;
 52     }
 53     void print()
 54     {
 55         cout<<"u="<<u<<","<<"v="<<v<<","<<"dis="<<dis<<endl;
 56     }
 57 } e[maxn*maxn];
 58 
 59 vector<Edge>edges;//存储新图的边
 60 vector<int>G[maxn];//记录临街的边号
 61 
 62 double Dis(int i,int j)
 63 {
 64     double x1=X[i],x2=X[j],y1=Y[i],y2=Y[j];
 65     return (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
 66 }
 67 
 68 int findx(int x)
 69 {
 70     if (p[x]==x) return x;
 71     else return p[x]=findx(p[x]);
 72 }
 73 
 74 void merge(int x,int y)
 75 {
 76     int px=findx(x);
 77     int py=findx(y);
 78     p[px]=py;
 79 }
 80 
 81 void init()
 82 {
 83     cin>>n;
 84     cnt=0;L=0;
 85     for(int i=1; i<=n; i++)
 86     {
 87         X[i]=nextnum();//坐标值实数
 88         Y[i]=nextnum();
 89         Peo[i]=nextint();
 90     }
 91     for(int i=1; i<=n; i++)
 92         for(int j=1; j<=n; j++)
 93         {
 94             if (i==j) continue;
 95             e[cnt++]=(Edge){i,j,Dis(i,j)};//建图
 96         }
 97 }
 98 
 99 void prim()//最小生成树&&构建新的图
100 {
101     for(int i=1;i<=n;i++) G[i].clear();
102     edges.clear();
103     for(int i=1; i<=n; i++) p[i]=i;
104     sort(e,e+cnt);
105 
106     for(int i=0; i<cnt; i++)
107     {
108         int u=e[i].u,v=e[i].v;
109         double dis=e[i].dis;
110         int pu=findx(u),pv=findx(v);
111         if (pu==pv) continue;
112         L+=dis;
113         merge(u,v);
114         edges.push_back((Edge){u,v,dis});
115         G[u].push_back(edges.size()-1);
116         edges.push_back((Edge){v,u,dis});
117         G[v].push_back(edges.size()-1);
118 
119         if (edges.size()==2*(n-1)) break;
120     }
121 }
122 typedef pair<int,double> Node;//<上一个点,由起点到上一个点的通路上的最大值>
123 void max_dis()//找到最小生成树上的任意两点之间的通路的最大的边的长度,网上大多数版本是DFS实现,故写了BFS
124 {
125     memset(MaxDis,0,sizeof(MaxDis));
126     bool mark[maxn];
127     for(int i=1;i<=n;i++)
128     {
129         memset(mark,0,sizeof(mark));
130         queue<Node>Q;
131         Q.push(make_pair(i,0));
132         while(!Q.empty())
133         {
134             Node Kn=Q.front();Q.pop();
135             int u=Kn.first;double dis=Kn.second;
136             if (mark[u]) continue;
137             mark[u]=true;
138             int m=G[u].size();
139             for(int j=0;j<m;j++)
140             {
141                 Edge e=edges[G[u][j]];
142                 int v=e.v;
143                 if (MaxDis[i][v]>0) continue;//important,小技巧,因为存的是双向边,所以必须消除回退的影响
144                 dis=MaxDis[i][v]=max(Dis(u,v),dis);
145                 Q.push(make_pair(v,dis));
146             }
147         }
148     }
149 }
150 
151 int main()
152 {
153     int cas=0;
154     cin>>cas;
155     while(cas--)
156     {
157         init();
158         prim();
159         max_dis();
160         double ans=0;
161         for(int i=2; i<=n; i++)//枚举每一条道路
162             for(int j=1; j<i; j++)
163             {
164                 int A=Peo[i]+Peo[j];
165                 double B=L-MaxDis[i][j];
166                 ans=max(ans,A/B);
167             }
168         printf("%.2lf\n",ans);
169     }
170     return 0;
171 }

 

转载于:https://www.cnblogs.com/little-w/p/3595422.html


http://lihuaxi.xjx100.cn/news/275852.html

相关文章

System.Transactions介绍

在.Net Framework 2.0中&#xff0c;新增了一个名称空间&#xff1a;System.Transactions。从其名字就可以看出来&#xff0c;里面包含了Transaction相关的类。System.Transactions提供了一个“轻量级”的、易于使用的Transaction框架。 在以前&#xff0c;要实现Transaction需…

类选择器和所作用的标签一起写为什么不起作用? - CSDN博客

原文:类选择器和所作用的标签一起写为什么不起作用&#xff1f; - CSDN博客HTML代码&#xff1a; css样式&#xff1a; 这不是将样式作用于circle类下的有current类的li标签吗&#xff1f;为什么不起作用&#xff1f; 原因&#xff1a; 选择器理解错误&#xff01; 一般常用的选…

wps在线预览接口_文档在线预览的实现

最近在研究企业文档管理&#xff0c;这个是基本上所有企业都需要的软件&#xff0c;当然也是有很多种解决方案。对于企业文档来说&#xff0c;最基本的需求就是独立存储&#xff0c;共享。这种需求只需要建立一个Windows共享文件夹或者架一个Samba服务器即可实现&#xff0c;无…

你知道为什么Java的main方法必须是public static void?

点击上方“方志朋”&#xff0c;选择“设为星标”回复”666“获取新整理的面试资料来源&#xff1a;http://suo.im/6v9d64Main 方法是我们学习 Java 编程语言时知道的第一个方法&#xff0c;你是否曾经想过为什么 main 方法是 public、static、void 的。当然&#xff0c;很多人…

985 CV 找不到工作? 4 点诚恳建议

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达本文转自|视觉算法【新智元导读】985研究生&#xff0c;学计算机视觉&#xff0c;出来后找不到工作&#xff1f;新智元带你看看这个70万浏览量问题下的答案干货&#xff1…

10月1日之后,你新建的GitHub库默认分支不叫「master」了

点击上方“视学算法”&#xff0c;选择加"星标"重磅干货&#xff0c;第一时间送达本文转载自&#xff1a;机器之心 | 作者&#xff1a;张倩、杜伟从 2020 年 10 月 1 日开始&#xff0c;GitHub 上的所有新库都将用中性词「main」命名&#xff0c;取代原来的「maste…

android webview mailto,Webview email link (mailto)

问题I have a view and view the site has malito code to send email.When I open the link opens in an error.I want that when I open the link opens Gmail app or another email application.Thanks to all helpers.public class teacher extends Activity implements On…

论文解读 | 微信看一看实时Look-alike推荐算法

作者丨gongyouliu编辑丨lily来源 | 授权转载自大数据与人工智能(ID:ai-big-data)微信看一看的精选文章推荐(见下面图1)大家应该都用过&#xff0c;微信团队在今年发表了一篇文章来专门介绍精选推荐的算法实现细节(Real-time Attention based Look-alike Model&#xff0c;简称R…