BZOJ3714: [PA2014]Kuglarz

BZOJ3714: [PA2014]Kuglarz

https://lydsy.com/JudgeOnline/problem.php?id=3714

分析:

  • 询问(lsim r)转化成(l-1)(r)
  • 新加一个(0),把询问看成连边就是要求一棵最小生成树。
  • prim即可

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <vector>
#include <cmath>
using namespace std;
#define N 2050
typedef long long ll;
int n,a[N][N];
char buf[100000],*p1,*p2;
int dis[N],vis[N];
ll ans;
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {
	int x=0; char s=nc();
	while(s<'0') s=nc();
	while(s>='0') x=(((x<<2)+x)<<1)+s-'0',s=nc();
	return x;
}
int main() {
	n=rd();
	int i,j;
	for(i=1;i<=n;i++) {
		for(j=i;j<=n;j++) {
			a[i-1][j]=rd(); a[j][i-1]=a[i-1][j];
		}
		dis[i]=0x3f3f3f3f;
	}
	int x=0,nxt=0;
	vis[0]=1;
	for(i=1;i<=n;i++) {
		nxt=0;
		for(j=1;j<=n;j++) {
			if(!vis[j]) {
				dis[j]=min(dis[j],a[x][j]);
				if((!nxt)||dis[j]<dis[nxt]) nxt=j;
			}
		}
		x=nxt; ans+=dis[x]; vis[x]=1;
	}
	printf("%lld
",ans);
}
原文地址:https://www.cnblogs.com/suika/p/10205650.html