• 洛谷1546 最短网络Agri-Net【最小生成树】【prim】


    【内含最小生成树Prim模板】

    题目https://www.luogu.org/problemnew/show/P1546

    题意:给定一个邻接矩阵。求最小生成树。

    思路:点少边多用Prim。

    Prim其实是把已经在最小生成树里的节点缩成一个,用priorityqueue每次找到距离当前最小生成树距离最小的那条边,加入树中。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<map>
     4 #include<set>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<cmath> 
     9 #include<stack>
    10 #include<queue>
    11 #include<iostream>
    12 
    13 #define inf 0x3f3f3f3f
    14 using namespace std;
    15 typedef long long LL;
    16 typedef pair<int, int> pr;
    17 
    18 int n;
    19 const int maxn = 1005;
    20 int head[maxn], tot = 0;
    21 struct edge{
    22     int to, nxt, w;
    23 }e[maxn * maxn];
    24 
    25 void add(int x, int y, int w)
    26 {
    27     e[++tot].to = y;
    28     e[tot].w = w;
    29     e[tot].nxt = head[x];
    30     head[x] = tot;
    31 //    e[++tot].to = x;
    32 //    e[tot].w = w;
    33 //    e[tot].nxt = head[y];
    34 //    head[y] = tot;
    35 }
    36 
    37 int ans = 0;
    38 int d[maxn];
    39 bool vis[maxn];
    40 int prim(int s)
    41 {
    42     priority_queue<pr, vector<pr>, greater<pr> >que;
    43     memset(d, 0x3f, sizeof(d));
    44     int num = 1;
    45     vis[s] = true;
    46     for(int i = head[s]; i; i = e[i].nxt){
    47         if(e[i].to != 1){
    48             que.push(make_pair(e[i].w, e[i].to));
    49             d[e[i].to] = min(d[e[i].to], e[i].w);
    50         }
    51     }
    52     while(!que.empty() && num != n){
    53         while(!que.empty() && vis[que.top().second])que.pop();
    54         if(que.empty())break;
    55         int x = que.top().second;
    56         vis[x] = true;
    57         ans += que.top().first;que.pop();
    58         num++;
    59         for(int i = head[x]; i; i = e[i].nxt){
    60             if(!vis[e[i].to] && d[e[i].to] > e[i].w){
    61                 que.push(make_pair(e[i].w, e[i].to));
    62                 d[e[i].to] = e[i].w;
    63             }
    64         }
    65     }
    66     if(num != n)return -1;
    67     else return ans;
    68 }
    69  
    70 int main()
    71 {
    72     scanf("%d", &n);
    73     for(int i = 1; i <= n; i++){
    74         for(int j = 1; j <= n; j++){
    75             int w;
    76             scanf("%d", &w);
    77             if(i != j){
    78                 add(i, j, w);
    79             }
    80         }
    81     }
    82     printf("%d
    ", prim(1));
    83 }
  • 相关阅读:
    Linux网络编程--socket
    UDP学习总结
    TCP协议学习总结
    DNS协议总结
    DHCP协议总结
    ARP协议总结
    二层协议--MPLS协议总结
    二层协议--LLDP协议总结
    二层协议--LACP协议总结
    二层协议--STP协议总结
  • 原文地址:https://www.cnblogs.com/wyboooo/p/11095968.html
Copyright © 2020-2023  润新知