您的位置:首页 > 其它

ZOJ 1586 QS Network 最小生成树

2017-05-11 20:43 253 查看
  这个题的题意好坑啊,花了好久去理解题意,而且另一个比较坑的点就是没给出n的范围?至少我没找到,自己根据经验估计了一个上限值。

  题意是每个人有一个路由器,第二行给出的n的数,代表第i个人购买一个路由器需要的权。 下面给出n×n的方阵mp,mp[i][j]代表第i和第j个人之间建立连接需要花费的权。

  注意:每个路由器只能和一台路由器通信。也就是说每个人和其它人建立连接时,双方都得购买一次路由器。

  于是在这里需要将问题小小的转化一下,也就是说mp[i][j]的权值应该更新为
mp[i][j] = mp[i][j] + cost[i] + cost[j];
其中,cost[i]是第i个人购买路由器需要的权。题目其实还是比较水的,prim一次就过了。

//
//  main.cpp
//  L
//
//  Created by LucienShui on 2017/5/11.
//  Copyright © 2017年 LucienShui. All rights reserved.
//

#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <cstdio>
#include <cstring>
#define memset(a,b) memset(a,b,sizeof(a))

using namespace std;

const int maxn = (int)1e3+7;
int mp[maxn][maxn],cost[maxn],dist[maxn],n;
bool vis[maxn];

inline void prim() {
int index,cur=1,sum=0;
for(int i=1 ; i<=n ; i++) dist[i] = mp[cur][i];
memset(vis,false);
vis[cur]=true;
for(int cnt=1 ; cnt<n ; cnt++) {
int minn = 1008611;
for(int i=2 ; i<=n ; i++) {
if(!vis[i]&&dist[i]<minn) {
index = i;
minn = dist[i];
}
}
vis[index] = true;
sum += dist[index];
for(int i=2 ; i<=n ; i++) {
if(!vis[i]&&mp[index][i]<dist[i]) {
dist[i] = mp[index][i];
}
}
}
printf("%d\n",sum);
}
inline void read() {
scanf("%d",&n);
for(int i=1 ; i<=n ; i++) {
scanf("%d",cost+i);
}
for(int i=1 ; i<=n ; i++) {
for(int j=1 ; j<=n ; j++) {
scanf("%d",mp[i]+j);
mp[i][j]+=cost[i]+cost[j];
}
}
}

int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int t;
scanf("%d",&t);
while(t--) {
read();
prim();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息