比赛 20190521热身赛 评测结果 AAAAAAAAAA
题目名称 挖水井 最终得分 100
用户昵称 subaru 运行时间 0.096 s
代码语言 C++ 内存使用 15.04 MiB
提交时间 2019-05-21 19:31:37
显示代码纯文本
#include <cmath>
#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>

#define maxn 310
#define maxe 90010

using namespace std;

inline int read(){
	int op=1,aa=0;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')op=-1;c=getchar();}
	while(c>='0'&&c<='9'){aa=aa*10+c-'0';c=getchar();}
	return op*aa;
}

int n;

int cnt;
int head[maxn];
struct Edge{int w,s,to,nxt;}edge[maxe];

inline void add_edge(int u,int v,int w){
	cnt++;
	edge[cnt].w=w;
	edge[cnt].s=u;
	edge[cnt].to=v;
	edge[cnt].nxt=head[u];
	head[u]=cnt;
}

bool cmp(Edge a,Edge b){
	return a.w<b.w;
}

int fa[maxn];

inline int find(int x){
	return fa[x]==x?x:fa[x]=find(fa[x]);
}

int kruskal(){
	for(register int i=1;i<=n;i++) fa[i]=i;
	int ans=0;
	int cnt_=0;
	for(int i=1;i<=cnt;i++){
		int u=edge[i].s,v=edge[i].to;
		if(find(u)==find(v))continue;
		ans+=edge[i].w;
		fa[find(u)]=find(v);
		cnt_++;
		if(cnt_==n)break;
	}
	return ans;
}

int main(){
	freopen("water.in","r",stdin);
	freopen("water.out","w",stdout);
	n=read();
	for(int i=1;i<=n;i++){
		int w=read();
		add_edge(0,i,w);
	}
	for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){
		int p=read();
		if(i!=j)add_edge(i,j,p);
	}
	sort(edge+1,edge+cnt+1,cmp);
	printf("%d\n",kruskal());
	return 0;
}