首页 > 编程语言 >prim算法(洛谷P1547)

prim算法(洛谷P1547)

时间:2023-03-31 22:45:30浏览次数:55  
标签:prim int 农场 43 P1547 ans 洛谷

P1547 [USACO05MAR]Out of Hay S

模板

/*
B1682 [Usaco2005 Mar]Out of Hay 干草危机
洛谷P1547 [USACO05MAR]Out of Hay S
====关键词===================================================
prim算法(最小生成树)
1.WA,没有加重复边的判断
2.加了重复边的判断,还是WA,但分数高了一点
3.照着别人AC的代码重写了逻辑,过了
====关键词===================================================
====题目===================================================
题目描述
Bessie 计划调查N(2≤N≤2000)个农场的干草情况,它从1 号农场出发。农场之间总共有
M(1≤M≤10^4)条双向道路,所有道路的总长度不超过10^9。有些农场之间存在着多条道路,所有的农场之间都是连通的。
Bessie 希望计算出该图中最小生成树中的最长边的长度。
输入格式
第 1 行输入两个整数N 和M; 接下来M 行,每行输入三个整数,表示一条道路的起点终点和长度。
输出格式
一个整数,表示最小生成树中的最长边的长度。
样例输入
Copy to Clipboard
3 3
1 2 23
2 3 1000
1 3 43
样例输出
Copy to Clipboard
43
由 1 到达 2,需要经过长度 23 的道路;回到 1 再到 3,通过长度 43 的道路.最长道路为 43
提示
没有写明提示
题目来源
Silver
====题目===================================================
*/
#include <iostream>
using namespace std;
const int INF = 0x7fffffff;
const int N = 2001; //农场数量上限
int a[N][N];        //地图矩阵
int n;              //农场数量
int m;              //边数量
int ans;            //答案
// prim算法需要的变量
bool visited[N];
struct
{
    int pre;  //距离结点最近的,前面的结点
    int dist; //最小生成树中该节点到pre结点距离
} closedge[N];
void showClosedgeVisited(); //显示伴随参数和visited[]
/*
prim算法
*/
void prim()
{
    //初始化变量
    for (int i = 1; i <= n; i++)
    {
        visited[i] = false;
        closedge[i].pre = -1;
        closedge[i].dist = INF;
    }
    //第一个结点直接写
    closedge[1] = {-1, 0};
    visited[1] = true;
    for (int i = 1; i <= n; ++i) //更新1的临近结点
        closedge[i].dist = a[i][1];

    //之后执行n-1次操作
    for (int kk = 1; kk <= n - 1; kk++)
    {
        //找到closedge[]中dist最小的结点,更新visited
        int min_dist = INF;
        int min_index = -1;
        for (int j = 1; j <= n; j++)
        {
            if (!visited[j] && closedge[j].dist < min_dist)
            {
                min_dist = closedge[j].dist;
                min_index = j;
            }
        }
        visited[min_index] = true;
        //更新答案
        if (closedge[min_index].dist > ans) //更新答案
            ans = closedge[min_index].dist;
        //找相邻结点,更新closedge[]
        for (int j = 1; j <= n; j++)
            if (!visited[j] && a[min_index][j] < closedge[j].dist)
            { // j结点未确定最小距离&&j结点到已确定最小值的结点集合的距离应最小
                closedge[j] = {min_index, a[min_index][j]};
            }
    }
}
int main()
{
    //读数据
    scanf("%d%d", &n, &m);
    //图初始化
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
        {
            if (i != j)
                a[i][j] = INF;
            else
                a[i][j] = 0;
        }
    while (m--)
    {
        int s, e, dis; //起点,终点,距离
        scanf("%d%d%d", &s, &e, &dis);
        if (s == e) //去掉环(本题好像没有环)
            continue;
        if (a[s][e] != 0 && dis > a[s][e]) //去掉重复边
            continue;
        a[s][e] = a[e][s] = dis;
    }
    //题解
    prim();

    // for (int i = 2; i <= n; i++)
    // { //找到最小生成树中最长的边
    //     if (closedge[i].dist > ans)
    //     {
    //         ans = closedge[i].dist;
    //     }
    // }
    //输出结果
    // showClosedgeVisited();
    printf("%d\n", ans);
    return 0;
}

void showClosedgeVisited()
{//便于调试
    cout << "下标 ";
    for (int i = 1; i <= n; i++)
    {
        cout << i << " ";
    }
    cout << endl;
    cout << "visited ";
    for (int i = 1; i <= n; i++)
    {
        cout << visited[i] << " ";
    }
    cout << endl;
    cout << "index ";
    for (int i = 1; i <= n; i++)
    {
        cout << closedge[i].pre << " ";
    }
    cout << endl;
    cout << "dist ";
    for (int i = 1; i <= n; i++)
    {
        cout << closedge[i].dist << " ";
    }
    cout << endl;
}

 

标签:prim,int,农场,43,P1547,ans,洛谷
From: https://www.cnblogs.com/FishSmallWorld/p/17277677.html

相关文章

  • 洛谷P1908 逆序对
    题目描述猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai​>aj​且 i<j 的有序对。......
  • 洛谷P3374 【模板】树状数组 1-(单点修改,区间查询)
    题目描述如题,已知一个数列,你需要进行下面两种操作:将某一个数加上 x求出某区间每一个数的和输入格式第一行包含两个正整数 n,m,分别表示该数列数字的个数和操作的总个数。第二行包含 n 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。接下来 ......
  • 洛谷P3368 【模板】树状数组 2-(区间修改,单点查询)
    题目描述如题,已知一个数列,你需要进行下面两种操作:将某区间每一个数加上 x;求出某一个数的值。输入格式第一行包含两个整数 N、M,分别表示该数列数字的个数和操作的总个数。第二行包含 N 个用空格分隔的整数,其中第 i 个数字表示数列第 i 项的初始值。接下来......
  • 洛谷 P5642 - 人造情感(换根 dp)
    想起来很轻松,写起来很酸爽的套路题。默认以\(1\)为根。先考虑怎么算单个\(f(u,v)\),我们定义一个连通块的权值为从该连通块中选出若干条点不相交的路径,选出的路径的权值之和的最大值。那么显然\(f(u,v)\)就是整棵树的权值\(-\)挖掉\((u,v)\)这条路径后各个连通块的权值之......
  • 洛谷9150题解
    考虑把\(i\tok_i\)连边,这样形成若干个环。考虑断环为链并且把链复制一份接到后面。考虑求出从一个点集开始拓展能够到达的点集\(S1_i\)。显然\(S1_i\)在环上是连续的,设\(r_i\)表示第\(i\)个节点拓展能得到的右端点。考虑每个节点\(i\)所在强连通分量的点集合\(S2\)。可以证明\(......
  • PrimeFaces主题选择器
    PrimeFaces主题选择器作者:chszsPrimeFaces集成了ThemeRollerCSS框架,而且预置了37种主题样式。可以使用在线的ThemeRoller主题产生器工具生成自定义的主题。应用一个主题到P......
  • PrimeFaces布局技巧
    PrimeFaces布局技巧作者:chszs布局组件Layout是一个高度可定制的边框布局模型,它可以很轻松地创建复杂的网页布局,即使不懂Web设计。一、布局组件Layout的属性布局组件Layout的......
  • C++ primer第十五章总结
    1oop的思想是数据抽象继承和动态绑定数据抽象可以将类的接口与实现分离;继承动态绑定,又称运行时绑定2虚函数是基类希望其派生类进行覆盖的函数<1>任何构造函......
  • 洛谷P1036 选数
    1#include<bits/stdc++.h>2usingnamespacestd;3intn,k,a[25];4inthk;//这个是k个数加起来的和5intsum;//这个是个数(输出的那个)6intpdzhi(intx){......
  • 洛谷P1020
    P1020[NOIP1999普及组]导弹拦截思考这题很显然是一道DP题,第一问就是求该序列的最长不下降子序列.先说最长不下降子序列的\(O(n^2)\)的做法.用\(dp_k\)表示第\(k\)......