BZOJ3714: [PA2014]Kuglarz
BZOJ3714: [PA2014]Kuglarz
题面
题解
思维题
题意是问你最小花费多少可以使得知道1--N的所有数的值
而你每次可以知道L-R的值
而知道第i个数的值需要知道第1-i-1的值和1-i的值
所以你一共要知道1-0到1-n的所有值
跑最小生成树即可
#include<bits/stdc++.h> using namespace std; const int MAXN = 2000 + 10; inline int read() { int f=1,x=0; char ch; do { ch=getchar(); if(ch=='-') f=-1; }while(ch<'0'||ch>'9'); do { x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }while(ch>='0'&&ch<='9'); return f*x; } int n,m; struct node { int from; int to; int val; friend bool operator < (node a1,node a2) { return a1.val<a2.val; } }g[MAXN * MAXN - 10]; int cnt=0; int fa[MAXN*MAXN + 10]; inline void addedge(int a,int b,int c) { ++cnt;g[cnt].from=a;g[cnt].to=b;g[cnt].val=c;return; } inline int find(int x) { if(x==fa[x]) return x; else return fa[x]=find(fa[x]); } long long sum=0; int tot=0; int main() { n=read(); for(int i=1;i<=n;i++) { for(int j=i;j<=n;j++) { m+=1; int val=read(); addedge(i-1,j,val); } } for(int i=1;i<=n;i++) fa[i]=i; sort(g+1,g+m+1); for(int i=1;i<=m;i++) { int u=g[i].from,v=g[i].to; int fu=find(u),fv=find(v); if(fu!=fv) { sum+=g[i].val; tot++; if(tot==n) { break; } fa[fu]=fv; } } cout<<sum<<endl; }