【最小生成树】洛谷P5994 [PA2014]Kuglarz

(吟唱)转换题意——

Link


题目

【最小生成树】洛谷P5994 [PA2014]Kuglarz_第1张图片


  • 每个点的情况都要知道
  • i的奇偶可以通过询问 i <-> j 和 i+1 <-> j 或 i<->i 得到
  • i,j区间的价格转化为边的权值,边连接i-1和j
  • 然后我们通过连上所有的点,就可以通过各种加减计算后,得到一种得到所有暗藏球的杯子的方案
  • 建最小生成树使花费的价格最少

Code

#include
#include
#include
using namespace std;
int n,h,t,x,y,js,f[10001];
long long ans,z;
struct asdf{
 int xx,yy;
 long long zz;
} Q[10000001];
int find(int d){  //并查集
 if(f[d] == d) return d;
 return f[d] = find(f[d]);
}
bool cmp(asdf aa, asdf bb){return aa.zz<bb.zz;}  //按权值从小到大
int main(){
 scanf("%d",&n);
 for(int i = 1; i <= n; f[i]=i,++i)  //输入
   for(int j = i; j <= n; ++j) {
      scanf("%lld",&z); 
      Q[++t] = (asdf){i-1,j,z};  //建边
      Q[++t] = (asdf){j,i-1,z};
   }
 sort(Q+1,Q+1+t,cmp); h = 1; js = 1;  //排序,准备建最小生成树
 while(h<=t&&js<=n){
     x = Q[h].xx, y = Q[h].yy, z = Q[h].zz;
  if(find(x)!=find(y)){  //不在同个联通块
   ++js;   //计数
   ans += z;  //+答案
   f[find(x)] = find(y);
  }
  ++h;
 }
 printf("%lld",ans);
 return 0;
}

你可能感兴趣的:(图论)