首页 > 其他分享 >计蒜客:圣诞树(dijkstra,特殊的生成树)

计蒜客:圣诞树(dijkstra,特殊的生成树)

时间:2024-11-12 23:40:57浏览次数:1  
标签:int root child visited dijkstra 圣诞树 minHeap 计蒜客 dis

 

基础原理:特殊的生成树

给定一张无向图,其中边权都是正数,你需要求出总代价最小的生成树,生成树上每条边 (u,v)(u,v) 的代价为 w(u,v)∗count(v)w(u,v)∗count(v),其中 w(u,v)w(u,v) 为边 (u,v)(u,v) 的权值,count(v)count(v) 是 vv 所在子树的结点数总和。

解法:虽然看起来是一道生成树的题,实际上却是一道单源最短路的题目。我们把整棵树的代价加起来,实际上就等于从根结点出发到每个顶点的最短路之和。因此,从每个顶点出发求一遍单源最短路,取其中最短路总和最小的一个顶点作为根,其到所有顶点的单源最短路的总和就是最终答案。

但这题还给结点加上了权值,我们在计算结点的贡献值时需要乘上结点的权值(其实我没搞懂为啥直接乘就行了,不过推几个样例就能得到这个结果)。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n, m;
 4 long long maximum = 0x3f3f3f3f;
 5 long long res = 0;  
 6 typedef pair<int, int> pii;
 7 
 8 vector<pii> graph[50005];
 9 vector<int> weight(50005, 0);
10 int dis[50005];
11 set<pii, less<pii> > minHeap;
12 bool visited[50005];
13 
14 bool dijkstra(int p) {
15     memset(visited, false, sizeof(visited));
16     memset(dis, 0x3f, sizeof(dis));
17     minHeap.clear();
18     minHeap.insert(make_pair(0, p));
19     dis[p] = 0;
20     visited[p] = true;
21     
22     while(!minHeap.empty()) {
23         auto node = minHeap.begin();
24         int root = node -> second;
25         minHeap.erase(node);
26         visited[root] = true;
27         if (dis[root] >= maximum) { //存在无法到达的结点
28             return false;
29         }
30         res += dis[root] * weight[root]; //计算总价值
31         
32         for (auto iter : graph[root]) {
33             if (!visited[iter.first]) {
34                 int child = iter.first;
35                 int value = iter.second;
36                 if (value + dis[root] < dis[child]) {
37                     minHeap.erase(make_pair(dis[child], child));
38                     dis[child] = dis[root] + value;
39                     minHeap.insert(make_pair(dis[child], child));
40                 }
41             }
42         }
43     }
44     return true;             
45 }
46 int main() {
47     cin >> n >> m;
48     for (int i = 1; i <= n; ++ i) {
49         scanf("%d", &weight[i]);
50     }
51     int a, b, c;
52     for (int i = 0; i < m; ++ i) {
53         cin >> a >> b >> c;
54         graph[a].push_back(make_pair(b, c));
55         graph[b].push_back(make_pair(a, c));
56     }
57     if (dijkstra(1)) { //树根固定为1
58         cout << res;
59     } else {
60         cout << "No Answer";
61     }
62     
63 }

 

标签:int,root,child,visited,dijkstra,圣诞树,minHeap,计蒜客,dis
From: https://www.cnblogs.com/coderhrz/p/18542882

相关文章

  • 计蒜客:骑车比赛(Dijkstra)
     学习堆优化的写法1#include<bits/stdc++.h>2usingnamespacestd;3intn,m,a,b,c;4typedefpair<int,int>pii;//first表示距离,second表示节点号5vector<pii>graph[1005];6set<pii>minHeap;7vector<int>dis(1005,INT32_MAX);......
  • 计蒜客:网络延迟(DFS/BFS)
     题目要求的是最远的两个节点的距离,即求树的直径(树中所有最短路径距离的最大值即为树的直径 求树的直径有两种做法,两次bfs(或者dfs),另一种是用树形DP本文用两次DFS实现#include<bits/stdc++.h>usingnamespacestd;intn,u,v;vector<int>graph[50005];vector<bool>vi......
  • 计蒜客:最短路简化版(BFS)
     在queue中用结束标识来节约队列空间。也可以用vector来实现队列,用[left,right]控制队列。1#include<bits/stdc++.h>2usingnamespacestd;3intn,m,c;4vector<int>graph[1005];5vector<bool>visited(1005,false);6vector<int>level(1005,0);7queu......
  • 计蒜客:互粉攻略(DFS/BFS)
     因为有重复数据,所以不得不等输入完以后再进行有向图的遍历。1#include<bits/stdc++.h>2usingnamespacestd;3intn,m;4set<int>graph[1005];5vector<bool>visited(1005,false);6vector<pair<int,int>>degree(1005,make_pair(0,0));//(入度,出度)......
  • 计蒜客:修建大桥(并查集/DFS/BFS)
     找到有几张连通图即可解决问题。DFS:1#include<bits/stdc++.h>2usingnamespacestd;3intn,m;4intgraph[1005][1005]={0};5boolvisited[1005]={false};6voiddfs(intp){7if(visited[p]){8return;9}10visited[p]......
  • 计蒜客:公告板(线段树)
     难点在于要把模型抽象出来。第一眼看到题面,想到的是以公告板的高度作为线段树的区间,但看到h<=10^9以后,感觉又开不了这么大的数组。但实际上,最多只有n块公告,所以最极端的情况下不过只有n行,所以区间的真正大小是[1,min(n,h)]。解决了区间的问题,再来考虑每个节点要维护的信息。......
  • 计蒜客:最甜的苹果(线段树)
     样例输入5612345Q15U36Q34Q45U29Q15样例输出5659 这题我们需要维护的信息,从区间的和变成了区间内的最大值。现在区间的内的某个值可能增大可能减小,若从上到下(从根到叶)进行节点更新,我们无法直接判断目前区间内的最大的节点。所以维护区间......
  • 图(邻接矩阵)知识大杂烩!!(邻接矩阵结构,深搜,广搜,prim算法,kruskal算法,Dijkstra算法,拓扑排序)(
     小伙伴们大家好,今天给大家带来图(邻接矩阵)的各种知识,让你看完此文章彻底学会邻接矩阵的相关问题。1.邻接矩阵表示方法1.1知识讲解 我们用一个二维数组arr来表示图。若图为有向图,其中arr【i】【j】=w表示i号点和j号点之间的距离为w,如果i和j之间无路可以设定w=0或无穷。(根......
  • 圣诞树html网页代码实操代码详解
    下面是一个简单的HTML网页代码,用于展示一个ASCII艺术风格的圣诞树,以及一些基本的样式。你可以将以下代码复制并粘贴到一个HTML文件中,然后用浏览器打开即可查看效果。```html<!DOCTYPEhtml><htmllang="zh"><head>  <metacharset="UTF-8">  <metaname="viewpor......
  • 计蒜客:斑点蛇(线段树)
     样例输入 1012345678910Query13Add36Query27Sub102Add63Query310End  样例输出 63359采用标准模板即可。注意线段树的节点个数一般为其范围的4倍。1#include<bits/stdc++.h>2usingnamespacestd;3vector<int>s(5000......