布线问题
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:
1、把所有的楼都供上电。
2、所用电线花费最少
-
输入
-
第一行是一个整数n表示有n组测试数据。(n<5)
每组测试数据的第一行是两个整数v,e.
v表示学校里楼的总个数(v<=500)
随后的e行里,每行有三个整数a,b,c表示a与b之间如果建铺设线路花费为c(c<=100)。(哪两栋楼间如果没有指明花费,则表示这两栋楼直接连通需要费用太大或者不可能连通)
随后的1行里,有v个整数,其中第i个数表示从第i号楼接线到外界供电设施所需要的费用。( 0<e<v*(v-1)/2 )
(楼的编号从1开始),由于安全问题,只能选择一个楼连接到外界供电设备。
数据保证至少存在一种方案满足要求。
输出
- 每组测试数据输出一个正整数,表示铺设满足校长要求的线路的最小花费。 样例输入
-
1 4 6 1 2 10 2 3 10 3 1 10 1 4 1 2 4 1 3 4 1 1 3 5 6
样例输出
-
4
-
第一行是一个整数n表示有n组测试数据。(n<5)
1)典型的最小生成树问题;有n个点,连接n - 1条线,使的权值之和最小, 裸prime算法
2)这种问题还有另一种问法,就是n个点,连接n - 1条线,使的权值之和最大(常见的是:奸商为了挣钱,要求路线话费最大, 从而其挣得钱就越多!太贱了);这种情况就是第一种情况的变化,稍微变化一下可以求解,输入边的时候取相反数,那么最后求解的最小即是负值最小,其绝对值也就是为整数的最大。
/*************************************************************************
> File Name: mst.c
> Author: xzl
> Mail:xiaolongqdu@gmail.com
> Created Time: 2013年11月19日 星期二 09时50分51秒
************************************************************************/
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#define Max_len 600
#define MAX 1000000
using namespace std;
typedef struct node{
int var;
int weight;
}node;
int v, e;
int Min;
int mincost[Max_len];
vector<node>map[Max_len];
void prim(int var);
int main(){
int n, i;
int a, b, c, temp;
node no, no1;
scanf("%d", &n);
while(n--){
memset(mincost, 0, sizeof(mincost));
scanf("%d %d", &v, &e);
for(i = 0; i < e; i++){
scanf("%d %d %d", &a, &b, &c);
no.var = b; no.weight = c;
no1.var = a; no1.weight = c;
map[a].push_back(no);
map[b].push_back(no1);
}
scanf("%d", &Min);
for(i = 1; i < v; i++){
scanf("%d", &temp);
if(Min > temp){
Min = temp;
}
}
prim(1);
for(i = 1; i <= v; i++){
map[i].clear();
}
}
}
void prim(int var){
int i;
int intree[Max_len] = {0};
int var_temp, wei, num, cost;
for(i = 1; i <= v; i++){
mincost[i] = MAX;
}
mincost[var] = 0;
while(!intree[var]){
intree[var] = 1;
for(i = 0; i < map[var].size(); i++){
var_temp = map[var][i].var;
wei = map[var][i].weight;
if(wei < mincost[var_temp] && !intree[var_temp]){
mincost[var_temp] = wei;
}
}
var = 1;
num = MAX;
for(i = 1; i <= v; i++){
if(!intree[i] && mincost[i] < num){
num = mincost[i];
var = i;
}
}
}
cost = Min;
for(i = 1; i <= v; i++){
cost += mincost[i];
}
printf("%d\n", cost);
}
最小生成树,是图论中最基本的了,不会的筒子们,还等神马!