【MST-prime】HDU 1102 Constructing Roads
题意
- 以邻接矩阵的形式给出各点之间的距离,然后再给出Q条已经建好的道路,让我们求最小的建造路径的成本使得各点间相互贯通。
思路
- 因为每两个点中间的边都给了,所以这是一幅稠密图,但是N的范围在100内,所以我们采用prime算法。
prime算法
(历经暑假放假已经完全忘光了QAQ)
- 我们需要做的是维护点到树上的距离。
- 我们从随便一个点开始,然后用这个点去松弛其他的点。该点标记
- 找到dis 最小的结点,再松弛其他未被标记过的点。该点标记
- 一直到所有的点进行完松弛操作为止
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <list>
#include <map>
#define INF 0x3f3f3f3f
#define MID l + r >> 1
#define lsn rt << 1
#define rsn rt << 1 | 1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
using namespace std;
typedef long long ll;
const int maxN = 1000 + 5;
int N, mp[105][105];
int dis[maxN], vis[maxN];
int prime()
{
int ans = 0;
memset(vis, 0, sizeof(vis));
for(int i = 1 ; i <= N ; i++)
dis[i] = ( i == 1 ? 0 : INF);
for(int i = 1 ; i <= N ; i++)
{
int minn = INF, min_pos = 0;
for(int j = 1 ; j <= N ; j ++)
{
if(!vis[j] && dis[j] < minn)
{
minn = dis[j];
min_pos = j;
}
}
vis[min_pos] = 1;
ans += minn;
for(int j = 1 ; j <= N ; j ++)
{
if(dis[j] > mp[min_pos][j])
dis[j] = mp[min_pos][j];
}
}
return ans;
}
int main()
{
while(~scanf("%d", &N))
{
for(int i = 1 ; i <= N ; i ++)
for(int j = 1 ; j <= N ; j ++)
scanf("%d", &mp[i][j]);
int Q; scanf("%d", &Q);
while(Q -- )
{
int a, b;
scanf("%d%d", &a, &b);
mp[a][b] = 0;
mp[b][a] = 0;
}
printf("%d\n", prime());
}
return 0;
}