您的位置:首页 > 其它

ural Electrification Plan 最小生成树,多个源点

2015-08-26 14:48 281 查看
多个源点,虚拟成一个超点

题意:有很多岛,有些岛上有电站,岛与岛之间铺光缆可以互相通电。求使全部岛通电的最小代价。
本来是很朴素的最小生成树,但是不止一个岛有电站就使得这个问题变成多个源点的问题

处理是重新构造图,将所有电站当作一个点,边(电站,无电岛)

最小生成树可以有超点,那最短路可不可以呢?联想上一道行星的题,求从底层一个点到顶层点的最短路,那可不可以把最顶的节点当成一个超点??怎么实现?这道题目测不可以。再仔细想,比如单源最短路dijstra算法球的是源点到每个点的最短距离,所以终止是一个还是多个并不影响。

生成树要的是未加入tree的点与树中连接边最小的,所以可以有。

再想,网络流的可不可以。。这个不熟悉。。留着。。

const int N=110;
const int INF=21460000;
struct edge{
int x,y,c;
bool operator < (const edge& a)const { return c<a.c; }
}e[N*N];
int n,k;
int Index
,fa
,mat

;

int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}

int main()
{
int x,y,ans,cnt;
cin >> n >> k;
memset(Index,0,sizeof(Index));

for(int i=0;i<k;i++){ cin >> x;  Index[x]=1;  }

k=2;
for(int i=1;i<=n;i++){
if(Index[i])continue;
Index[i]=k++;
}
memset(mat,INF,sizeof(mat));
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int tcost; cin >> tcost;
mat[Index[i]][Index[j]]=min(mat[Index[i]][Index[j]],tcost);
}
}
cnt=0;
for(int i=1;i<k;i++){
for(int j=i+1;j<k;j++){
e[cnt].x=i;e[cnt].y=j;e[cnt++].c=mat[i][j];
   }
}
sort(e,e+cnt);
// for(int i=0;i<cnt;++i) printf("%d %d %d \n",e[i].u,e[i].v,e[i].val );
// printf("\n");
ans=0;
for(int i=1;i<k;i++)fa[i]=i;
for(int i=0;i<cnt;i++){
int l,r;
l=find(e[i].x);r=find(e[i].y);
if(l!=r){
fa[r]=l;
ans+=e[i].c;
}
}
cout << ans << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: