4
13
2016
0

[BZOJ3714] [PA2014]Kuglarz

神转化。。。

首先我们考虑因为每一次只会知道奇偶性,所以我们对于一个区间[l,r]是否有球至少保证要知道[l...r]全部的奇偶性才可以判定每个杯子下面是否有球。(意味着如果每个杯子抽象成点,那么这些点之间必须全部连通才会知道每个杯子下面是否有球)

因为要费用最少,所以我们每次选择费用最小且有用的边加上去

然后就变成了最小生成树了。。。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

int n,en,h[2005],cnt,f[2005];
long long ans=0;

struct Edge{
int a,b,v;
friend bool operator<(Edge a,Edge b){return a.v<b.v;}
}e[4000005];

void AddEdge(int sa,int sb,int sc){
e[++en].a=sa;
e[en].b=sb;
e[en].v=sc;
}

int Find(int x){return x==f[x]?x:f[x]=Find(f[x]);}
void Union(int sa,int sb){f[sb]=sa;}

void Read(int &x){
char ch;
while((ch=getchar())<'0' || ch>'9');
x=ch-'0';
while((ch=getchar())>='0' && ch<='9')x=x*10+ch-'0';
}

int main(){
freopen("3714.in","r",stdin);
freopen("3714.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
	for(int j=i;j<=n;j++){
		int x;
		scanf("%d",&x);
		AddEdge(i,j+1,x);
	}
}
sort(e+1,e+en+1);
for(int i=1;i<=n+1;i++)f[i]=i;
for(int i=1;i<=en && cnt<=n;i++){
	if(Find(e[i].a)!=Find(e[i].b)){Union(Find(e[i].a),Find(e[i].b));ans+=(long long)e[i].v;cnt++;}
}
printf("%lld\n",ans);
return 0;
}
Category: BZOJ | Tags: OI bzoj | Read Count: 560

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com