• Codeforces Round 597 (Div. 2) D (最小生成树)


    题目链接:Codeforces Round 597 (Div. 2) D

    1. // Problem: D. Shichikuji and Power Grid
    2. // Contest: Codeforces - Codeforces Round 597 (Div. 2)
    3. // URL: https://codeforces.com/contest/1245/problem/D
    4. // Memory Limit: 256 MB
    5. // Time Limit: 2000 ms
    6. //
    7. // Powered by CP Editor (https://cpeditor.org)
    8. #include<bits/stdc++.h>
    9. using namespace std;
    10. typedef long long ll;
    11. typedef pair<int,int> pii;
    12. const int N=2e5+5;
    13. const int M=N*2;
    14. const int P=1e6;
    15. struct edge{
    16. int sx,sy,ex,ey;
    17. ll w;
    18. };
    19. vector<int> p;
    20. vector<edge> v;
    21. int find(int x){ //并查集
    22. if(p[x]!=x){
    23. p[x]=find(p[x]);
    24. }
    25. return p[x];
    26. }
    27. void add(int sx,int sy,int ex,int ey,ll w){ //建树,分别是两个点的坐标和边值
    28. v.push_back({sx,sy,ex,ey,w});
    29. }
    30. bool cmp(edge a,edge b){ //按边值排序
    31. return a.w<b.w;
    32. }
    33. int main(){
    34. int n;
    35. cin>>n;
    36. vector<int> x(n+1),y(n+1); //坐标
    37. map<ll,int> mp; //离散化
    38. mp[0]=0;
    39. map<pii,int> s; //离散化
    40. int tot=1;
    41. for(int i=1;i<=n;i++){
    42. cin>>x[i]>>y[i]; //输入坐标
    43. mp[1ll*x[i]*P+y[i]]=tot; //给点编号
    44. tot++;
    45. s[{x[i],y[i]}]=i; //这个坐标是第几个城市
    46. }
    47. p.assign(tot+1,0);
    48. for(int i=1;i<=tot;i++){
    49. p[i]=i;
    50. }
    51. vector<int> c(n+1),k(n+1);
    52. for(int i=1;i<=n;i++){ //输入建立发电站需要的成本以及建树
    53. cin>>c[i];
    54. add(0,0,x[i],y[i],c[i]);
    55. }
    56. for(int i=1;i<=n;i++){ //输入拉线需要的成本
    57. cin>>k[i];
    58. }
    59. for(int i=1;i<=n;i++){
    60. for(int j=i+1;j<=n;j++){ //遍历两个点
    61. int sx=x[i],sy=y[i]; //坐标
    62. int ex=x[j],ey=y[j];
    63. int d=abs(sx-ex)+abs(sy-ey); //两个城市的距离
    64. ll w=1ll*d*(k[i]+k[j]); //每两个城市拉线的成本
    65. add(sx,sy,ex,ey,w); //建树
    66. }
    67. }
    68. sort(v.begin(),v.end(),cmp); //树里面排序
    69. ll ans=0;
    70. vector<pii> path; //需要链接哪两个城市
    71. vector<int> city; //在哪个城市建发电站
    72. for(int i=0;i<v.size();i++){
    73. int sx=v[i].sx,sy=v[i].sy,ex=v[i].ex,ey=v[i].ey,w=v[i].w;
    74. int a=mp[1ll*P*sx+sy],b=mp[1ll*P*ex+ey]; //编号
    75. a=find(a),b=find(b); //判断是否在同一个树上
    76. if(a!=b){
    77. p[a]=b; //合并集合
    78. ans+=w; //费用等于两个点之间所需要花费的
    79. int x=s[{sx,sy}],y=s[{ex,ey}];
    80. if(sx==0&&sy==0){ //
    81. city.push_back(y); //
    82. }
    83. else{
    84. path.push_back({x,y});
    85. }
    86. }
    87. }
    88. cout<<ans<<"\n";
    89. cout<<city.size()<<"\n";
    90. for(auto x:city){
    91. cout<<x<<' ';
    92. }
    93. cout<<"\n";
    94. cout<<path.size()<<"\n";
    95. for(auto x:path){
    96. cout<<x.first<<' '<<x.second<<"\n";
    97. }
    98. return 0;
    99. }

  • 相关阅读:
    分布式事务理论和解决方案
    使用Docker搭建ELK,并与SpringBoot集成
    ES 8.14 向量搜索优化
    文件操作详解
    MySQL支持哪些存储引擎
    【计算机网络】互联网公司的网络架构和业务场景
    C51--蓝牙HC-08
    SpringCloud 三种服务调用方式,你学会了吗?
    MongoDB脑裂恢复
    uni-app开发微信小程序时u-view自定义样式不生效
  • 原文地址:https://blog.csdn.net/m0_73896521/article/details/133419398