tyvj 1666 城市建设【最小生成树】

-Wall是个好东西,要不然我至死都看不出来我把(b[i]+b[j])写成了(b[i],b[j])……
还是来自lyd的题解:

(其实原来课件第一行式子写错了没有-1,然而我用sai手画了一个上去hhhh,板绘选手表示鼠绘真难)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
long long n,a[N],b[N],h[N],tot,r,f[N],con;
long long ans;
char c[55][55];
struct qwe
{
	long long u,v,w;
	qwe(long long U=0,long long V=0,long long W=0)
	{
		u=U,v=V,w=W;
	}
}e[N];
bool cmp(const qwe &a,const qwe &b)
{
	return a.w<b.w;
}
long long zhao(long long x)
{
	return x==f[x]?x:f[x]=zhao(f[x]);
}
int main()
{
	scanf("%d",&n);
	for(long long i=1;i<=n;i++)
		scanf("%d",&b[i]);
	for(long long i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(long long i=1;i<=n;i++)
		scanf("%d",&h[i]);
	for(long long i=1;i<=n;i++)
		ans+=h[i]*(b[i]+a[i]-1)*(a[i]-1-b[i]+1)/2;//cerr<<ans<<endl;
	for(long long i=1;i<=n;i++)
		scanf("%s",c[i]+1);
	for(long long i=1;i<=n;i++)
		f[i]=i;
	scanf("%d",&r);
	for(long long i=1;i<=n;i++)
		for(long long j=1;j<i;j++)
		{
			if(c[i][j]=='N')
			{
				if(h[i]>h[j])
					e[++tot]=qwe(i,j,h[i]*b[j]*(a[i]-b[i])+h[j]*a[i]*(a[j]-b[j])+r*(b[i]+b[j]));
				else
					e[++tot]=qwe(i,j,h[j]*b[i]*(a[j]-b[j])+h[i]*a[j]*(a[i]-b[i])+r*(b[i]+b[j]));
			}
			else
			{
				if(h[i]>h[j])
					ans+=h[i]*b[j]*(a[i]-b[i])+h[j]*a[i]*(a[j]-b[j]);
				else
					ans+=h[j]*b[i]*(a[j]-b[j])+h[i]*a[j]*(a[i]-b[i]);
				long long fu=zhao(i),fv=zhao(j);
				if(fu!=fv)
					f[fu]=fv,con++;
			}
		}
	sort(e+1,e+1+tot,cmp);
	for(long long i=1;i<=tot&&con<n-1;i++)
	{
		long long fu=zhao(e[i].u),fv=zhao(e[i].v);
		if(fu!=fv)
		{
			f[fu]=fv;
			con++;
			ans+=e[i].w;
		}
	}
	printf("%lld\n",ans);
	return 0;
}
posted @ 2018-09-19 09:08  lokiii  阅读(167)  评论(0编辑  收藏  举报