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;
}
497

被折叠的 条评论
为什么被折叠?



