题意:$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$端点各做一次。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=2e5+,INF=0x3f3f3f3f;
int n,q,tot;
struct thxorz{
int u,v,w;
thxorz(int u=,int v=,int w=):u(u),v(v),w(w){}
inline bool operator <(const thxorz&A)const{return w<A.w;}
}e[N<<];
inline int adj(int x){return x==n?:(~x?x:n-);}
int minv1[N],minv2[N],edge[N];
int s,tmp,res;
ll ans;
int anc[N];
inline int get_anc(int x){return anc[x]==x?x:anc[x]=get_anc(anc[x]);}
inline void kruskal(){
sort(e+,e+tot+);for(register int i=;i<n;++i)anc[i]=i;
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;
} int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(n),read(q);
memset(minv1,0x3f,sizeof minv1),memset(minv2,0x3f,sizeof minv2),memset(edge,0x3f,sizeof edge);
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);
tmp=INF;for(register int i=;i<n;++i)if(MIN(tmp,minv1[i]))s=i;tmp=INF;
for(register int i=s,cnt=;cnt<=n;i=adj(i+),++cnt){if((tmp+=)>minv1[i]+)tmp=minv1[i]+;MIN(edge[i],tmp);}
tmp=INF;for(register int i=;i<n;++i)if(MIN(tmp,minv2[i]))s=i;tmp=INF;
for(register int i=s,cnt=;cnt<=n;i=adj(i+),++cnt){if((tmp+=)>minv2[i]+)tmp=minv2[i]+;MIN(edge[i],tmp);}
for(register int i=;i<n;++i)e[++tot]=thxorz(i,adj(i+),edge[i]);
kruskal();
return printf("%lld\n",ans),;
}

总结:等效转化的应用。当边如果某些方面连边有规律的时候,利用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. [Comet OJ - Contest #4 D][39D 1584]求和_"数位dp"

    求和 题目大意: 数据范围: 题解: 脑筋急转弯可还行..... 我们发现只需要最后枚举个位/xk/xk 因为前面的贡献都是确定的了. 故此我们最后暴力统计一下就好咯. 不知道为啥我组合数一直过不去, ...

  2. svn服务器端的更新操作

    svn up需要在 非svn库中进行操作 ,一般在网站www目录下操作

  3. spring boot 使用elasticsearch

    在文章开始之前我们先来介绍一下elasticsearch 是一个分布式的 RESTful 风格的搜索和数据分析引擎. 查询 : Elasticsearch 允许执行和合并多种类型的搜索 — 结构化.非 ...

  4. linux下selenium+phantomjs环境

    # 安装依赖软件yum -y install wget fontconfig # 下载PhantomJSwget -P /tmp/ https://bitbucket.org/ariya/phanto ...

  5. kdress学习

    这两天看了一本书叫<linux二进制分析>,这里面提到的一个小工具kdress,这里分析一下 源码在:https://github.com/elfmaster/kdress kdress介 ...

  6. nginx+keepalived高可用

    准备工作: yum install -y gcc openssl-devel pcre-devel install iptables-services setenforce 0 sed -ri 's/ ...

  7. jvm调试相关:jmap失效下找到alternatives神器

    1.使用 jmap <pid>出现的错误日志:很明显是版本问题 Error attaching to process: sun.jvm.hotspot.runtime.VMVersionM ...

  8. centos安装配置mariadb

    CentOS7下使用yum安装MariaDB CentOS 6 或早期的版本中提供的是 MySQL 的服务器/客户端安装包,但 CentOS 7 已使用了 MariaDB 替代了默认的 MySQL.M ...

  9. day10 mysql常用操作

    一. 目录 1.mysql的简介 2.增删改查操作 3.单表查询 4.多表查询常见的三种方式 5.pymysql模块操作数据库 二. 内容 一.mysql的简介  概述:mysql是一个关系型数据库, ...

  10. 解决docker pull 速度慢问题

    解决docker pull 速度慢问题 将docker镜像源修改为国内的: 在 /etc/docker/daemon.json 文件中添加以下参数(没有该文件则新建): { "registr ...