ural 1982. Electrification Plan 【最小生成树】

1982. Electrification Plan

Time limit: 0.5 second
Memory limit: 64 MB
Some country has  n cities. The government has decided to electrify all these cities. At first, power stations in  k different cities were built. The other cities should be connected with the power stations via power lines. For any cities  ij it is possible to build a power line between them in c ij roubles. The country is in crisis after a civil war, so the government decided to build only a few power lines. Of course from every city there must be a path along the lines to some city with a power station. Find the minimum possible cost to build all necessary power lines.

Input

The first line contains integers  n and  k (1 ≤  k ≤  n ≤ 100). The second line contains  k different integers that are the numbers of the cities with power stations. The next  n lines contain an  n ×  ntable of integers { c ij} (0 ≤  c ij ≤ 10 5). It is guaranteed that  c ij =  c jic ij > 0 for  i ≠  jc ii = 0.

Output

Output the minimum cost to electrify all the cities.

Sample

input output
4 2
1 4
0 2 4 3
2 0 5 2
4 5 0 1
3 2 1 0
3
Problem Author: Mikhail Rubinchik 

/*
    题意:给你n个城市和k个发电站的位置,以及每个城市之间拉电线的费用,
          求使所有城市都能得到供电的最小花费
    类型:最小生成树
    分析:把有发电站的城市之间的费用全部改成0,再跑一次最小生成树即可
*/

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
#define int_inf ((1<<31)-1)
#define ll_inf ((1ll<<63)-1)

int lowcost[100000+100];
int vis[100000+100];
int Map[300][300];
bool dian[100000+100];
int n;
int prime()
{
    for(int i=1;i<=n;i++){
        lowcost[i]=Map[1][i];
    }
    int Min;
    int ans=0;
    lowcost[1]=0;
    vis[1]=1;
    for(int i=1;i<n;i++){
        Min=int_inf;
        int k;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&Min>lowcost[j]){
                Min=lowcost[j];
                k=j;
            }
        }
        vis[k]=true;
        ans+=Min;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&lowcost[j]>Map[k][j])
                lowcost[j]=Map[k][j];
        }
    }
    return ans;
}
int main()
{
    int m;
    while(scanf("%d%d",&n,&m)!=EOF){
        memset(dian,0,sizeof(dian));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=m;i++){
            int a;
            scanf("%d",&a);
            dian[a]=1;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                int c;
                scanf("%d",&c);
                Map[i][j]=c;
                if(dian[i]==1&&dian[j]==1)Map[i][j]=0;
            }
        }
        int result=prime();
        printf("%d\n",result);
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值