nyoj38布线问题

来源:互联网 发布:来肯云商软件怎么样 编辑:程序博客网 时间:2024/05/22 10:49

布线问题

时间限制: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开始),由于安全问题,只能选择一个楼连接到外界供电设备。
数据保证至少存在一种方案满足要求。
输出
每组测试数据输出一个正整数,表示铺设满足校长要求的线路的最小花费。
样例输入
14 61 2 102 3 103 1 101 4 12 4 13 4 11 3 5 6
样例输出
4

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 1000000using 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);}

最小生成树,是图论中最基本的了,不会的筒子们,还等神马!

0 0