Atcoder CODE FESTIVAL 2016 Final G - Zigzag MST[最小生成树]
题意:$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[最小生成树]的更多相关文章
- @atcoder - CODE FESTIVAL 2017 Final - J@ Tree MST
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定 N 个点,第 i 点有一个点权 Xi,再给定一棵边带权的树 ...
- Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution
Atcoder CODE FESTIVAL 2016 Grand Final E - Water Distribution 题目链接:https://atcoder.jp/contests/cf16- ...
- Atcoder CODE FESTIVAL 2016 qual C 的E题 Encyclopedia of Permutations
题意: 对于一个长度为n的排列P,如果P在所有长度为n的排列中,按照字典序排列后,在第s位,则P的value为s 现在给出一个长度为n的排列P,P有一些位置确定了,另外一些位置为0,表示不确定. 现在 ...
- CODE FESTIVAL 2016 Final 题解
传送门 \(A\) 什么玩意儿-- const char c[]={"snuke"}; char s[15];int n,m; int main(){ scanf("%d ...
- 【AtCoder】CODE FESTIVAL 2016 qual B
CODE FESTIVAL 2016 qual B A - Signboard -- #include <bits/stdc++.h> #define fi first #define s ...
- 【AtCoder】CODE FESTIVAL 2016 qual A
CODE FESTIVAL 2016 qual A A - CODEFESTIVAL 2016 -- #include <bits/stdc++.h> #define fi first # ...
- 【AtCoder】CODE FESTIVAL 2016 qual C
CODE FESTIVAL 2016 qual C A - CF -- #include <bits/stdc++.h> #define fi first #define se secon ...
- 【赛时总结】 ◇赛时·IV◇ CODE FESTIVAL 2017 Final
◇赛时-IV◇ CODE FESTIVAL 2017 Final □唠叨□ ①--浓浓的 Festival 气氛 ②看到这个比赛比较特别,我就看了一看--看到粉粉的界面突然开心,所以就做了一下 `(* ...
- [AtCoder Code Festival 2017 QualB D/At3575] 101 to 010 - dp
[Atcoder Code Festival 2017 QualB/At3575] 101 to 010 有一个01序列,每次可以选出一个101,使其变成010,问最优策略下能操作几次? 考虑像 11 ...
随机推荐
- Linux-echo:打印彩色输出
脚本可以使用转义序列在终端中生成彩色文本 文本颜色是由对应的色彩码来描述的.其中包括: 重置=0,黑色=30,红色=31,绿色=32, 黄色=33,蓝色=34,洋红=35,青色=36,白色=37. 要 ...
- Kafka如何实现每秒上百万的高并发写入
Kafka是高吞吐低延迟的高并发.高性能的消息中间件,在大数据领域有极为广泛的运用.配置良好的Kafka集群甚至可以做到每秒几十万.上百万的超高并发写入. 那么Kafka到底是如何做到这么高的吞吐量和 ...
- Spring5的总体架构图
Spring5的主体架构图 主要是四大部分:Web.Data Access/Integration.Core Container.中间层,具体见下图:
- Lua格式讲解
firstValue = "This is a string value"; -- 这是一个变量的定义,变量定义不需要任何标记,这个是全局变量 print("helloW ...
- js变量浅拷贝 深拷贝
js的变量分为简单数据类型和复杂数据类型(即引用类型). 简单数据类型在内存中占据着固定大小的空间,被保存在栈内存中,在简单数据类型中,当一个变量指向另一个变量时,只是创建了值的副本,两个变量只是占用 ...
- ajax-springMVC提交表单的方式
1.request参数提交(Form提交),适用于GET/POST request参数传递都会转换成 id=123&fileName=test.name&type=culture_ar ...
- 基于S7协议实现与西门子PLC通信
西门子PLC是目前工控行业市场占有额比较大的一款PLC,而且随着上位机的越来越普及, 有很多人开始考虑自己开发上位机实现与西门子PLC的通信,遇到的第一个问题就是数据通信. 其实西门子PLC提供的接口 ...
- svn经典总结
大佬的svn:http://www.cnblogs.com/armyfai/p/3985660.html#!comments https://www.cnblogs.com/0zcl/p/730976 ...
- 阿里巴巴开源框架java诊断工具--Arthas
下载:arthas wget https://alibaba.github.io/arthas/arthas-boot.jar java -jar arthas-boot.jar --target-i ...
- Nginx如何配置防盗链
配置要点 none : 允许没有http_refer的请求访问资源: blocked : 允许不是http://开头的,不带协议的请求访问资源: 119.28.190.215 start.igrow. ...