题意:$n$个点,$q$次建边,每次建边选定$x,y$,权值$c$,然后接着$(y,x+1,c+1),(x+1,y+1,c+2),(y+1,x+2,c+3),(x+2,y+2,c+4)\dots$(画图理解),然后求最小生成树。


一开始想的是堆维护最小。。发现不行`````

这题是等效转化。回顾kruskal的过程,权值小的边被考虑过后对应的两个点一定是联通的。那么其实再考虑权值大的边的话,是可以改造的。当$(x,y)$被考虑过后,权值大的$(y,x+1)$其实就可以改成是$(x,x+1)$,都是等价的。$(x+1,y+1)$也可以改成是$(y,y+1)$。以此类推,就可以把除了起始状态的边以外的乱七八糟的连边全都搞到一个大环上,然后环上同一个相邻连边里取最小值,做Kruskal,一定是对的,这样一来因为边被搞少了很多,只有$O(n+q)$条边,就可以做kruskal了。

还有一个问题,每个点为起始点,往后相邻点连边,如果每次操作都绕环一圈更新每条边的min,显然T飞。又因为这是环状结构,所以直接找出最小的出发连边,这条边一定不会被后面的给更新掉,从她开始沿着环开始顺时针更新,一路上一遍做出发边前缀最小值一遍连边就可以了,这个要以$x$端点和$y$端点各做一次。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<cmath>
  6. #include<queue>
  7. #define dbg(x) cerr << #x << " = " << x <<endl
  8. #define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
  9. using namespace std;
  10. typedef long long ll;
  11. typedef double db;
  12. typedef pair<int,int> pii;
  13. template<typename T>inline T _min(T A,T B){return A<B?A:B;}
  14. template<typename T>inline T _max(T A,T B){return A>B?A:B;}
  15. template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
  16. template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
  17. template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
  18. template<typename T>inline T read(T&x){
  19. x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
  20. while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
  21. }
  22. const int N=2e5+,INF=0x3f3f3f3f;
  23. int n,q,tot;
  24. struct thxorz{
  25. int u,v,w;
  26. thxorz(int u=,int v=,int w=):u(u),v(v),w(w){}
  27. inline bool operator <(const thxorz&A)const{return w<A.w;}
  28. }e[N<<];
  29. inline int adj(int x){return x==n?:(~x?x:n-);}
  30. int minv1[N],minv2[N],edge[N];
  31. int s,tmp,res;
  32. ll ans;
  33. int anc[N];
  34. inline int get_anc(int x){return anc[x]==x?x:anc[x]=get_anc(anc[x]);}
  35. inline void kruskal(){
  36. sort(e+,e+tot+);for(register int i=;i<n;++i)anc[i]=i;
  37. for(register int i=;i<=tot;++i)if(get_anc(e[i].u)^get_anc(e[i].v))anc[get_anc(e[i].u)]=get_anc(e[i].v),ans+=e[i].w;
  38. }
  39.  
  40. int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
  41. read(n),read(q);
  42. memset(minv1,0x3f,sizeof minv1),memset(minv2,0x3f,sizeof minv2),memset(edge,0x3f,sizeof edge);
  43. for(register int i=,x,y,c;i<=q;++i)read(x),read(y),read(c),MIN(minv1[x],c),MIN(minv2[y],c),e[++tot]=thxorz(x,y,c);
  44. tmp=INF;for(register int i=;i<n;++i)if(MIN(tmp,minv1[i]))s=i;tmp=INF;
  45. for(register int i=s,cnt=;cnt<=n;i=adj(i+),++cnt){if((tmp+=)>minv1[i]+)tmp=minv1[i]+;MIN(edge[i],tmp);}
  46. tmp=INF;for(register int i=;i<n;++i)if(MIN(tmp,minv2[i]))s=i;tmp=INF;
  47. for(register int i=s,cnt=;cnt<=n;i=adj(i+),++cnt){if((tmp+=)>minv2[i]+)tmp=minv2[i]+;MIN(edge[i],tmp);}
  48. for(register int i=;i<n;++i)e[++tot]=thxorz(i,adj(i+),edge[i]);
  49. kruskal();
  50. return printf("%lld\n",ans),;
  51. }

总结:等效转化的应用。当边如果某些方面连边有规律的时候,利用kruskal过程,把权值相对某些边大的,转化为方便处理/减少连边的方案。

Atcoder CODE FESTIVAL 2016 Final G - Zigzag MST[最小生成树]的更多相关文章

  1. @atcoder - CODE FESTIVAL 2017 Final - J@ Tree MST

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定 N 个点,第 i 点有一个点权 Xi,再给定一棵边带权的树 ...

  2. Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution

    Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution 题目链接:https://atcoder.jp/contests/cf16- ...

  3. Atcoder CODE FESTIVAL 2016 qual C 的E题 Encyclopedia of Permutations

    题意: 对于一个长度为n的排列P,如果P在所有长度为n的排列中,按照字典序排列后,在第s位,则P的value为s 现在给出一个长度为n的排列P,P有一些位置确定了,另外一些位置为0,表示不确定. 现在 ...

  4. CODE FESTIVAL 2016 Final 题解

    传送门 \(A\) 什么玩意儿-- const char c[]={"snuke"}; char s[15];int n,m; int main(){ scanf("%d ...

  5. 【AtCoder】CODE FESTIVAL 2016 qual B

    CODE FESTIVAL 2016 qual B A - Signboard -- #include <bits/stdc++.h> #define fi first #define s ...

  6. 【AtCoder】CODE FESTIVAL 2016 qual A

    CODE FESTIVAL 2016 qual A A - CODEFESTIVAL 2016 -- #include <bits/stdc++.h> #define fi first # ...

  7. 【AtCoder】CODE FESTIVAL 2016 qual C

    CODE FESTIVAL 2016 qual C A - CF -- #include <bits/stdc++.h> #define fi first #define se secon ...

  8. 【赛时总结】 ◇赛时·IV◇ CODE FESTIVAL 2017 Final

    ◇赛时-IV◇ CODE FESTIVAL 2017 Final □唠叨□ ①--浓浓的 Festival 气氛 ②看到这个比赛比较特别,我就看了一看--看到粉粉的界面突然开心,所以就做了一下 `(* ...

  9. [AtCoder Code Festival 2017 QualB D/At3575] 101 to 010 - dp

    [Atcoder Code Festival 2017 QualB/At3575] 101 to 010 有一个01序列,每次可以选出一个101,使其变成010,问最优策略下能操作几次? 考虑像 11 ...

随机推荐

  1. MySQL_表数据操作

    目录 1.添加数据 2.添加多条数据 3.更新数据 4. 删除数据 5.查看表数据 1.添加数据 insert into <表名>[<字段名>[,...]] values(&l ...

  2. fedora使用

    1.更改ip 添加ip和掩码 sudo ifconfig p4p1 172.31.8.7/24 up 添加网关 sudo route add default gw 172.31.8.1   2.远程登 ...

  3. 关于MySQL 5.6 中文乱码的问题(尤其是windows的gbk编码)

    一般MySQL 数据库乱码由以下几种情况造成(按照顺序): 1. 创建数据库的时候没设置编码,解决办法: 就是在创建数据库的时候设置编码, 例如: CREATE DATABASE `mydb` CHA ...

  4. [AcWing303/304]任务安排2/3

    [AcWing303]任务安排2 有 \(N\) 个任务排成一个序列在一台机器上等待执行,它们的顺序不得改变.机器会把这 \(N\) 个任务分成若干批,每一批包含连续的若干个任务.从时刻 \(0\) ...

  5. Minimum Cost For Tickets

    In a country popular for train travel, you have planned some train travelling one year in advance.  ...

  6. 基于hanlp的es分词插件

    摘要:elasticsearch是使用比较广泛的分布式搜索引擎,es提供了一个的单字分词工具,还有一个分词插件ik使用比较广泛,hanlp是一个自然语言处理包,能更好的根据上下文的语义,人名,地名,组 ...

  7. Typora的使用-规整笔记 让我以后的笔记内容更加整齐

    以后我用typora写笔记使用这种排版方式, 且可以方便的看到大纲. 大标题二级标题 内容分类 三级标题 内容讲解 四级标题 内容分块 五级标题

  8. HDU-6704 K-th occurrence (后缀自动机father树上倍增建权值线段树合并)

    layout: post title: HDU-6704 K-th occurrence (后缀自动机father树上倍增建权值线段树合并) author: "luowentaoaa&quo ...

  9. linux 查找大文件

    查看磁盘使用情况:df -h [root@iZwz9gs2zseivevv1k5vnkZ /]# df -h Filesystem Size Used Avail Use% Mounted on /d ...

  10. 技能节-AI人脸识别

    我们收到技能节项目的通知是在两周之前,项目要求做个人脸评分系统. 两周时间写一个"人脸评分系统",好像时间比较紧了,还好我们完成了~这个项目是将摄像头捕获到的包含人脸的图像传输到百 ...