HDU 1102(PRIM)(多次的wa换来深刻的理解dij&&prim)

  We know that there are already some roads between some villages and your job is the build some roads such that all the  villages are connect and the length of all the roads built is minimum.


#include <bits/stdc++.h>
#define inf 1000000
using namespace std;

int g[210][210];
int low[210];
int vis[210]; // 表示该点是否已经加入最小生成树中
int n;

int prim()
{
    for (int i=0; i<n; ++i)
    {
        low[i] = g[0][i];
    }

    int ans = 0;
    memset(vis, 0, sizeof(vis));
    vis[0] = 1;

    for (int i=1; i<n; ++i)   // 循环n-1次,找剩下的n-1个点。(这里最关键切记次数不要循环多了否则最后会出现-1找不到的情况)
    {
        int k = -1, mindis = inf;
        for (int j=0; j<n; ++j)   // 循环找当前剩下的点中 距离最小生成树点集距离最短的点。
        {
            if (!vis[j] && low[j] < mindis)
            {
                mindis = low[j];
                k = j;
            }
        }

        if (k == -1) return -1;
        vis[k] = 1; // 加入最小生成树点集
        ans += mindis;

        for (int j=0; j<n; ++j)   // 更新没加入最小生成树的点中 距离是否会缩短。
        {
            if (!vis[j] && low[j] > low[k] + g[k][j])
            {
                low[j] = low[k] + g[k][j];
            }

            if (!vis[j] && low[j] > g[k][j])   // 上面的if是错的。low数组存储的距离是当前点到生成树中所有点距离最小的的点。
            {
                low[j] = g[k][j]; // 因为这个点加入最小生成树集合中,可以和其中任意一个点连一条边。
            }
        }
    }
    return ans;
}


int main()
{
    int q;
    while(cin >> n)
    {
        for (int i=0; i<n; ++i)
        {
            for (int j=0; j<n; ++j)
            {
                cin >> g[i][j];
            }
        }

        cin >> q;
        for (int i=0; i<q; ++i)
        {
            int a, b;
            cin >> a >> b;
            a--, b--;
            g[a][b] = 0;
            g[b][a] = 0;
        }

        int ans = prim();
        cout << ans << endl;
    }
    return 0;
}
我们知道在一些村庄之间已经有一些道路,你的工作是建造一些道路,这样所有的村庄都连接起来,所有道路的长度都是最小的。



输入

第一行是一个整数n(3<n<=100),这是村庄的数量。然后n行,其中第i个包含n个整数,这些n个整数的j个是I村和J村之间的距离(距离应该是1, 1000以内的整数)。


然后存在整数q(0<q<n=(n+1)/2)。然后是Q线,每条线包含两个整数A和B(1<A<B<N),这意味着A村和B村之间的道路已经建成
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值