ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

公路村村通

2021-05-27 23:02:27  阅读:229  来源: 互联网

标签:pq int 公路 st wt graph verN 村村通


公路村村通

现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。

输入格式:

输入数据包括城镇数目正整数N(≤ 1000)和候选道路数目M(≤ 3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。

输出格式:

输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。

输入样例:

6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3

输出样例:

12

 

解题思路

  最小生成树模板题。

  Prime算法的AC代码:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <vector>
 4 #include <queue>
 5 #include <map>
 6 
 7 const int INF = 0x3f3f3f3f;
 8 
 9 typedef std::pair<int, int> Pair;
10 
11 struct Edge {
12     int to, wt;
13 };
14 
15 struct Graph {
16     std::vector<std::vector<Edge> > G;
17     int verN, edgeN;
18 };
19 
20 Graph *createGraph(int n, int m);
21 int Prime(Graph *graph, int src);
22 
23 int main() {
24     int n, m;
25     scanf("%d %d", &n, &m);
26     Graph *graph = createGraph(n, m);
27     int minCost = Prime(graph, 0);
28     printf("%d", minCost);
29     
30     return 0;
31 }
32 
33 Graph *createGraph(int n, int m) {
34     Graph *graph = new Graph;
35     graph->verN = n;
36     graph->edgeN = m;
37     graph->G.resize(graph->verN);
38     
39     for (int i = 0; i < graph->edgeN; i++) {
40         int v, w, wt;
41         scanf("%d %d %d", &v, &w, &wt);
42         graph->G[v - 1].push_back({w - 1, wt});
43         graph->G[w - 1].push_back({v - 1, wt});
44     }
45     
46     return graph;
47 }
48 
49 int Prime(Graph *graph, int src) {
50     int dist[graph->verN];
51     std::fill(dist, dist + graph->verN, INF);
52     bool vis[graph->verN] = {false};
53     dist[src] = 0;
54     int vCount = 0, totalWt = 0;
55     
56     std::priority_queue<Pair, std::vector<Pair>, std::greater<Pair> > pq;
57     pq.push(Pair(dist[src], src));
58     
59     while (!pq.empty()) {
60         int v = pq.top().second;
61         pq.pop();
62         if (vis[v]) continue;
63         
64         vis[v] = true;
65         vCount++;
66         totalWt += dist[v];
67         for (std::vector<Edge>::iterator it = graph->G[v].begin(); it != graph->G[v].end(); it++) {
68             if (!vis[it->to] && it->wt < dist[it->to]) {
69                 dist[it->to] = it->wt;
70                 pq.push(Pair(dist[it->to], it->to));
71             }
72         }
73     }
74     
75     return vCount == graph->verN ? totalWt : -1;
76 }

   Kruskal算法的AC代码:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <vector>
 4 #include <queue>
 5 
 6 struct Edge {
 7     int to, wt;
 8 };
 9 
10 struct Graph {
11     std::vector<std::vector<Edge> > G;
12     int verN, edgeN;
13 };
14 
15 struct Pair {
16     int from, to, wt;
17 };
18 
19 Graph *createGraph(int n, int m);
20 int Kruskal(Graph *graph);
21 bool merge(int *st, int v, int w);
22 int find(int *st, int x);
23 bool operator<(const Pair &a, const Pair &b);
24 
25 int main() {
26     int n, m;
27     scanf("%d %d", &n, &m);
28     Graph *graph = createGraph(n, m);
29     int minCost = Kruskal(graph);
30     printf("%d", minCost);
31     
32     return 0;
33 }
34 
35 Graph *createGraph(int n, int m) {
36     Graph *graph = new Graph;
37     graph->verN = n;
38     graph->edgeN = m;
39     graph->G.resize(graph->verN);
40     
41     for (int i = 0; i < graph->edgeN; i++) {
42         int v, w, wt;
43         scanf("%d %d %d", &v, &w, &wt);
44         graph->G[v - 1].push_back({w - 1, wt});
45         graph->G[w - 1].push_back({v - 1, wt});
46     }
47     
48     return graph;
49 }
50 
51 int Kruskal(Graph *graph) {
52     std::priority_queue<Pair> pq;
53     for (int v = 0; v < graph->verN; v++) {
54         for (std::vector<Edge>::iterator it = graph->G[v].begin(); it != graph->G[v].end(); it++) {
55             pq.push({v, it->to, it->wt});
56         }
57     }
58     int st[graph->verN];
59     std::fill(st, st + graph->verN, -1);
60     int eCount = 0, totalWt = 0;
61     
62     while (!pq.empty()) {
63         int v = pq.top().from;
64         int w = pq.top().to;
65         int wt =pq.top().wt;
66         pq.pop();
67         if (merge(st, v, w)) {
68             eCount++;
69             totalWt += wt;
70         }
71     }
72     
73     return eCount == graph->verN - 1 ? totalWt : -1;
74 }
75 
76 bool merge(int *st, int v, int w) {
77     v = find(st, v);
78     w = find(st, w);
79     if (v == w) return false;
80     st[v] = w;
81     return true;
82 }
83 
84 int find(int *st, int x) {
85     return st[x] < 0 ? x : st[x] = find(st, st[x]);
86 }
87 
88 bool operator<(const Pair &a, const Pair &b) {
89     return a.wt > b.wt;
90 }

标签:pq,int,公路,st,wt,graph,verN,村村通
来源: https://www.cnblogs.com/onlyblues/p/14819781.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有