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

 

posted @ 2015-08-26 14:48  y丫t  阅读(442)  评论(0编辑  收藏  举报