Electrification Plan
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
i,
j
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.
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
×
n
table of integers {
c
ij} (0 ≤
c
ij
≤ 10
5). It is guaranteed that
c
ij
=
c
ji
,
c
ij
> 0 for
i
≠
j,
c
ii
= 0.
Output the minimum cost to electrify all the cities.
input | output |
---|---|
4 2 1 4 0 2 4 3 2 0 5 2 4 5 0 1 3 2 1 0 | 3 |
已经建好的加入到生成树里,费用为0,把剩下的加入生成树
最小生成树代码:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
int d[102],rode[102][102],n,k;
bool vis[102];
using namespace std;
int Prim()
{
memset(vis,0,sizeof(vis));
int ans=0;
while(1)
{
int v=-1;
for(int i=1; i<=n; i++)
if(!vis[i]&&(v==-1||d[v]>d[i]))
v=i;
if(v==-1)break;
vis[v]=1;
ans+=d[v];
for(int i=1; i<=n; i++)
if(!vis[i])
d[i]=min(d[i],rode[v][i]);
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
memset(d,INF,sizeof(d));
int i,j;
for(i=1; i<=k; i++)
{
int x;
scanf("%d",&x);
d[x]=0;
}
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
scanf("%d",&rode[i][j]);
printf("%d\n",Prim());
}
return 0;
}
把原来已有的电站归入一个并查集中,不断选择最优解最后保证联通
并查集代码:
#include<bits/stdc++.h>
int par[102],rank1[102],n,k;
using namespace std;
struct node
{
int from,to,cost;
}rode[10005];
bool cmp(node a,node b)
{
return a.cost<b.cost;
}
void init()
{
for(int i=0;i<=100;i++)
par[i]=i,rank1[i]=0;
}
int find(int x)
{
if(x==par[x])return x;
return par[x]=find(par[x]);
}
bool same(int x,int y)
{
return find(x)==find(y);
}
void unite(int x,int y)
{
x=find(x);y=find(y);
if(x==y)return;
if(rank1[x]<rank1[y])
par[x]=y;
else
{
par[y]=x;
if(rank1[x]==rank1[y])
rank1[x]++;
}
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
init();
int i,j;
for(i=1;i<=k;i++)
{
int x;scanf("%d",&x);
par[x]=-1;
}
int L=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
int x;scanf("%d",&x);
if(i==j)continue;
rode[L].to=j;
rode[L].from=i;
rode[L++].cost=x;
}
sort(rode,rode+L,cmp);
int ans=0;
for(i=0;i<L;i++)
{
node e=rode[i];
if(!same(e.from,e.to))
{
ans+=e.cost;
unite(e.from,e.to);
}
}
printf("%d\n",ans);
}
return 0;
}