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 ...
随机推荐
- Go语言中的打包和工具链
包 所有Go语言的程序都会组织成若干组文件,每组文件被称为一个包.这样每个包的代码都可以作为很小的复用单元,被其他项目引用. 包名惯例 给包命名的惯例是使用包所在目录的名字.并不需要所有包的名字都与别 ...
- Linux 安装 openoffice
1 说明 本文档采用rpm包方式安装,操作系统为centos 2 下载openoffice rpm包 创建nginx源码包存放目录 mkdir /usr/local/src/openoffice cd ...
- [转帖]服务器备份工具:Amanda,Bakula,Clonezilla,Rsnapshot,Mondo Rescue
服务器备份工具:Amanda,Bakula,Clonezilla,Rsnapshot,Mondo Rescue https://ywnz.com/linuxyffq/5270.html 改天试用一下. ...
- The import javax.websocket cannot be resolved的解决问题
在eclipse中导入项目的时候出现了这个问题,废了我半天劲,才搞明白,把问题记录下来,方便大家以后遇到这问题好处理.提供参考. 出现的问题截图: 因为我用的是tomcat8, 大体步骤:项目上点右键 ...
- matplotlib库之直方图
例题:假设你获取了250部电影的时长(列表a中),希望统计出这些电影时长的分布状态(比如时长为100分钟到120分钟电影的数量,出现的频率)等信息,你应该如何呈现这些数据? 一些概念及问题: 把数据分 ...
- 跑跑卡丁车(dp)
题意:https://www.nitacm.com/problem_show.php?pid=1470 #define IOS ios_base::sync_with_stdio(0); cin.ti ...
- MySQL-存储引擎-创建表-字段数据类型-严格模式-字段约束-键-02
目录 扩展点 查看服务端字符.IP.端口配置 取消本次错误输入 例外情况 database 数据库操作 table 数据表操作 查看MySQL存储引擎 常见几个存储引擎 InnoDB MyISAM M ...
- vue 动态添加对象属性
昨天使用vue发现直接给对象添加属性,并不能触发响应更新,后来看文档发现要通过this.$set 函数动态添加才可用,eg: this.$set( obj, key, data)
- nginx-consul-template
概述Consul-template 是 HashiCorp 基于 Consul 所提供的可扩展的工具,通过监听 Consul中的数据变化,动态地修改一些配置文件中地模板.常用于在 Nginx.HAPr ...
- thymeleaf 模板使用 之 前台界面获取后台属性值
使用Thymeleaf模板时,如果需要在js中获取后台传值,那么需要用内联JS写法获取 [姿势很重要] 一.后台通过Model的addAttribute方法向前台传值 1.js获取后台属性值(--内联 ...