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

多个源点,虚拟成一个超点 

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


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


最小生成树可以有超点,那最短路可不可以呢?联想上一道行星的题,求从底层一个点到顶层点的最短路,那可不可以把最顶的节点当成一个超点??怎么实现?这道题目测不可以。再仔细想,比如单源最短路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[N],fa[N],mat[N][N];

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

 

转载于:https://www.cnblogs.com/tinyork/p/4760395.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值