【BZOJ3943】【Usaco2015 Feb】SuperBull 最大生成树 Prim

来源:互联网 发布:itunes软件更新目录 编辑:程序博客网 时间:2024/06/10 07:35

链接:

#include <stdio.h>int main(){    puts("转载请注明出处[vmurder]谢谢");    puts("网址:blog.csdn.net/vmurder/article/details/44961149");}

题意:

给n个数,然后每次可以选择一对尚存活的数,将其异或和加和到答案中,然后删掉其中一个数,直到只剩一个数为止。

题解:

花样教人理解最小生成树,一片苦心啊,不会最小生成树的可以从这开始理解2333。
对了,数据范围有点大,完全图 kruscal 多个 log 估计过不去。

代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 2050#define inf 0x3f3f3f3fusing namespace std;int n,a[N];int dist[N];bool vis[N];long long prim(){    memset(dist,0xef,sizeof dist),dist[1]=0;    long long ret=0;    int i,j,x,t;    for(i=1;i<=n;i++)    {        t=-inf;        for(j=1;j<=n;j++)            if(!vis[j]&&dist[j]>t)                t=dist[j],x=j;        vis[x]=1;        ret+=dist[x];        for(j=1;j<=n;j++)            if(!vis[j])dist[j]=max(dist[j],(a[x]^a[j]));    }    return ret;}int main(){    freopen("test.in","r",stdin);    int i,j,k;    scanf("%d",&n);    for(i=1;i<=n;i++)scanf("%d",&a[i]);    cout<<prim()<<endl;    return 0;}
0 0