2529 间谍派遣 题解
2529. 间谍派遣
Description:
你是M,一个雇佣N个标号为从1到N的间谍的情报机关的总管。每个间谍被派往不同的国家并在那获取重要情报。
如下是你的任务:
1.在部分间谍间组织会面。每次会面在两个间谍间进行,两个间谍交换他们自己获取的或从之前会面中得到的信息。因为在不同国家的两个间谍间组织机密会面很困难,所以每次秘密会面都有一个费用。
2.当所有会面结束后,选择一部分间谍参加拯救世界的任务。一个间谍k参加此项任务需要花费Mk。很重要的一点是,任务要成功,必须满足参加任务的间谍获取的情报聚集到一起包含了其他剩余间谍所有的信息。
请找出完成任务的最小花费,即组织会面和派遣间谍的费用之和。
Input:
输入的第一行包含正整数N,表示间谍数目(2≤N≤1000)。
接下来的N行包含N个不超过10^6的非负整数。在k行m列的数字表示间谍k和m间会面的花费,同样的,与m行k列的数字相等,k=m时数字为0。
接下来的一行包含N个正整数Mk(1≤Mk≤10^6),分别为派遣间谍1,2,…,N参加任务的花费
Output:
只有一行,为所需的最小总费用。
Sample Input:
3
0 6 9
6 0 4
9 4 0
7 7 7
Sample Output:
17
Solve:
一道很明显的最小生成树的题,其实只需要把输入给出的邻接矩阵改成用结构体保存的边即可(注意相同的边只需要保存一次),之后直接跑一遍Kruskal就可以了,还有就是那个MK只要当成0到i的边的边权存入结构体就行。
关于Kruskal做最小生成树这里不详细解读了,之后会发篇文章,想看的可以去了解一下。
下面就到放出代码的时候了.
CODE:
#include <iostream>
#include <stdio.h>
#include <iomanip>
#include <algorithm>
#include <math.h>
#include <cstring>
#define r register
#define N 1000000
using namespace std;
const int M = 1500;
int ans, n, mapp[M][M], k, m, fa[N];
struct node {
int x, y, c;
}a[N];
int find(int x) {
if (fa[x] == x) {
return x;
} else {
fa[x] = find(fa[x]);
}
}
bool cmp (node x, node y) {
return x.c < y.c;
}
int kruskal() {
int k = 0;
for (r int i = 1; i <= n; ++ i) {
fa[i] = i;
}
sort(a + 1, a + m + 1, cmp);
for (r int i = 1; i <= m; ++ i) {
int p = find(a[i].x);
int q = find(a[i].y);
if (p != q) {
fa[p] = q;
ans += a[i].c;
}
}
}
int main() {
scanf("%d", &n);
for (r int i = 1; i <= n; ++ i) {
for (r int j = 1; j <= n; ++ j) {
scanf("%d", &mapp[i][j]);
if (i < j) {
a[++ m].x = i;
a[m].y = j;
a[m].c = mapp[i][j];
}
}
}
for (r int i = 1; i <= n; ++ i) {
scanf("%d", &k);
a[++ m].x = 0;
a[m].y = i;
a[m].c = k;
}
kruskal();
printf("%d", ans);
return 0;
}
本蒟蒻码风可能不太好看,望理解