BZOJ4912 SDOI2017天才黑客(最短路+虚树)

  容易想到把边当成点重建图跑最短路。将每条边拆成入边和出边,作为新图中的两个点,由出边向入边连边权为原费用的边。对于原图中的每个点,考虑由其入边向出边连边。直接暴力两两连边当然会被卡掉,注意到其边权是trie上lca的深度,由lca转rmq的做法可知,两点lca即为欧拉序区间中它们之间深度最小的点,于是跑出欧拉序后对入边出边的前后缀建虚点连边即可。当然每次连边时都需要将trie上有用的点提取出来,建虚树即可。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define N 50010
#define inf 2000000000
#define in(i) (i*2+n)
#define out(i) (i*2+n-1)
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{int x=0,f=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}
int T,n,m,k,p[N],t;
struct data{int to,nxt,len,s;
}edge[N];
vector<int> in_edge[N];
namespace trie
{int p[N],t,fa[N][18],deep[N],dfn[N],cnt;struct data{int to,nxt;}edge[N];void clear(){memset(p,0,sizeof(p));cnt=t=0;}void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}void dfs(int k){dfn[k]=++cnt;for (int i=p[k];i;i=edge[i].nxt){deep[edge[i].to]=deep[k]+1;fa[edge[i].to][0]=k;dfs(edge[i].to);}}void build(){fa[1][0]=1;dfs(1);for (int j=1;j<18;j++)for (int i=1;i<=k;i++)fa[i][j]=fa[fa[i][j-1]][j-1];}int lca(int x,int y){if (deep[x]<deep[y]) swap(x,y);for (int j=17;~j;j--) if (deep[fa[x][j]]>=deep[y]) x=fa[x][j];if (x==y) return x;for (int j=17;~j;j--) if (fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];return fa[x][0];}
}
namespace graph
{int p[N<<6],t,cnt,dis[N<<6];bool flag[N<<6];struct data{int to,nxt,len;}edge[N<<7];struct data2{int x,d;bool operator <(const data2&a) const{return d>a.d;}};priority_queue<data2> q;void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}void clear(){cnt=n+m*2;t=0;memset(p,0,sizeof(p));}void dijkstra(){for (int i=1;i<=cnt;i++) dis[i]=inf;dis[1]=0;memset(flag,0,sizeof(flag));q.push((data2){1,0});for (;;){while (!q.empty()&&flag[q.top().x]) q.pop();if (q.empty()) break;data2 x=q.top();q.pop();flag[x.x]=1;for (int i=p[x.x];i;i=edge[i].nxt)if (dis[x.x]+edge[i].len<dis[edge[i].to]){dis[edge[i].to]=dis[x.x]+edge[i].len;q.push((data2){edge[i].to,dis[edge[i].to]});}}}
}
namespace virtual_tree
{int a[N],tot,stk[N],id[N<<1],top,p[N],x[N],y[N],idin[N<<1],idout[N<<1],pre[N<<1],suf[N<<1],t,cnt;struct data{int to,nxt;}edge[N<<1];void addedge(int u,int v){t++;x[t]=u,y[t]=v;}void clear(){tot=top=t=cnt=0;}void push(int x){a[++tot]=x;}bool cmp(const int&a,const int&b){return trie::dfn[a]<trie::dfn[b];}void dfs(int k){id[++cnt]=k;idin[k]=graph::cnt+cnt;for (int i=p[k];i;i=edge[i].nxt){dfs(edge[i].to);id[++cnt]=k;}}void build(){if (tot==0) return;sort(a+1,a+tot+1,cmp);tot=unique(a+1,a+tot+1)-a-1;stk[++top]=1;for (int i=1+(a[1]==1);i<=tot;i++){int l=trie::lca(a[i],stk[top]);if (stk[top]!=l){while (top>1&&trie::deep[stk[top-1]]>=trie::deep[l]) addedge(stk[top-1],stk[top]),top--;if (stk[top]!=l) addedge(l,stk[top]);stk[top]=l;}stk[++top]=a[i];}while (top>1) addedge(stk[top-1],stk[top]),top--;for (int i=1;i<=t;i++) p[x[i]]=p[y[i]]=0;for (int i=1;i<=t;i++) edge[i].to=y[i],edge[i].nxt=p[x[i]],p[x[i]]=i;dfs(1);for (int i=1;i<=cnt;i++) idout[id[i]]=idin[id[i]]+cnt;graph::cnt+=cnt<<1;for (int i=1;i<=cnt;i++){pre[i]=++graph::cnt;graph::addedge(idin[id[i]],pre[i],0);if (i>1) graph::addedge(pre[i-1],pre[i],0);}for (int i=cnt;i>=1;i--){suf[i]=++graph::cnt;graph::addedge(suf[i],idout[id[i]],0);if (i<cnt) graph::addedge(suf[i],suf[i+1],0);}for (int i=1;i<=cnt;i++) graph::addedge(pre[i],suf[i],trie::deep[id[i]]);for (int i=1;i<=cnt;i++){pre[i]=++graph::cnt;graph::addedge(pre[i],idout[id[i]],0);if (i>1) graph::addedge(pre[i],pre[i-1],0);}for (int i=cnt;i>=1;i--){suf[i]=++graph::cnt;graph::addedge(idin[id[i]],suf[i],0);if (i<cnt) graph::addedge(suf[i+1],suf[i],0);}for (int i=1;i<=cnt;i++) graph::addedge(suf[i],pre[i],trie::deep[id[i]]);}
}
int main()
{
#ifndef ONLINE_JUDGEfreopen("bzoj4912.in","r",stdin);freopen("bzoj4912.out","w",stdout);const char LL[]="%I64d\n";
#elseconst char LL[]="%lld\n";
#endifT=read();while (T--){n=read(),m=read(),k=read();memset(p,0,sizeof(p));t=0;for (int i=1;i<=n;i++) in_edge[i].clear();for (int i=1;i<=m;i++){int x=read(),y=read(),len=read(),s=read();t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=len,edge[t].s=s,p[x]=t;}trie::clear();for (int i=1;i<k;i++){int x=read(),y=read(),z=read();trie::addedge(x,y);}trie::build();graph::clear();for (int i=p[1];i;i=edge[i].nxt)graph::addedge(1,out(i),0);for (int i=1;i<=m;i++) if (edge[i].to!=1) graph::addedge(in(i),edge[i].to,0);for (int i=1;i<=m;i++) graph::addedge(out(i),in(i),edge[i].len);for (int i=1;i<=m;i++) in_edge[edge[i].to].push_back(i);for (int i=1;i<=n;i++){virtual_tree::clear();for (int j=0;j<in_edge[i].size();j++) virtual_tree::push(edge[in_edge[i][j]].s);for (int j=p[i];j;j=edge[j].nxt) virtual_tree::push(edge[j].s);virtual_tree::build();for (int j=0;j<in_edge[i].size();j++) graph::addedge(in(in_edge[i][j]),virtual_tree::idin[edge[in_edge[i][j]].s],0);for (int j=p[i];j;j=edge[j].nxt) graph::addedge(virtual_tree::idout[edge[j].s],out(j),0);}graph::dijkstra();for (int i=2;i<=n;i++) printf("%d\n",graph::dis[i]);}return 0;
}

 

  

 

转载于:https://www.cnblogs.com/Gloid/p/10347036.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网页乱码解决小心得

出现乱码需要检查的项目&#xff1a;数据库编码、文件本身的字符集、html解析的字符集&#xff0c;如若上述项目编码一致仍然出现乱码&#xff0c;查看一下浏览器的编码&#xff0c;如果和设置的不一样说明上述设置有部分未成功&#xff0c;可以尝试使用header&#xff08;&…

https网络编程——如何利用中继证书(凭证)建立客户端证书

参考&#xff1a;如何利用中继证书&#xff08;凭证&#xff09;建立客户端证书 地址&#xff1a;https://qingmu.blog.csdn.net/article/details/108226592?spm1001.2014.3001.5502 目录建立客户端证书的前提是要建立中继证书建立客户端证书的具体步骤1、建立一个目录&#x…

分布式一致性协议Raft,以及难搞的Paxos

https://blog.csdn.net/colorant/article/details/73887706转载于:https://www.cnblogs.com/wzj4858/p/10350363.html

ffmpeg的新东东:AVFilter

http://blog.csdn.net/niu_gao/article/details/7219641 利用ffmpeg做图像的pixel format转换你还在用libswscale吗?嘿嘿,过时啦! ffmpeg中有了新东西:libavfilter.使用它,可以完全代替libswscale,并且可以自动完成一些复杂的转换操作呢.libavfilter啊,用了都说好!但就是太复杂…

https网络编程——HTTPS中SSL具体通信过程

参考:HTTPS中SSL是如何进行通信的? 地址:https://qingmu.blog.csdn.net/article/details/108277887?spm=1001.2014.3001.5502 目录 1、https中SSL通讯的前置准备工作2、openssl库相关函数介绍2.1、重要参数讲解3、SSL框架图4、demo4.1、sslserver.c4.2、sslclient.c1、http…

想跟着微软赛跑会累死你

当微软在推出ASP.NET1.1时,就发布了ASP.NET2.0测试版,当微软发布ASP.NET2.0时,又发布了ASP.NET AJAX测试版,当然也有不少人都知道,微软又有准备推出ASP.NET3.0版本的打算. 每一个版本比上一个版本都会有许多应用上的提升,一个重要的问题是:我们需要不需要和微软赛跑? 微软…

2019.2.4 nfs原理和安装实验

NFS 访问一个本地文件还是NFS共享文件对于客户端而言都是透明的&#xff0c;当文件打开的瞬间&#xff0c;内核会作出一个决定&#xff0c;如果是本地文件内核会将本地NFS共享文件内核会将NFS共享文件的所有引用传递给——》NFS客户端枢中 NFS客户端是通过TCP/IP协议及模块向NF…

基本 XAML 语法指南

我们介绍了 XAML 语法规则&#xff0c;以及用于描述 XAML 语法中存在的限制或选项的术语。当出现以下情况时你会发现本主题很有用&#xff1a;不熟悉 XAML 语言的使用&#xff0c;希望加强对术语或某些语法部分的理解&#xff0c;或者对 XAML 语言的工作原理感兴趣&#xff0c;…

https网络编程——如何做web的访问控制机制(ACL)

参考&#xff1a;如何做web的访问控制机制&#xff08;ACL&#xff09;&#xff1f; 地址&#xff1a;https://qingmu.blog.csdn.net/article/details/108286660?spm1001.2014.3001.5502 目录ACL含义例子具体实现ACL含义 对于一个服务器来说&#xff0c;我们不能让随随便便一…

形容人的内核是什么意思_成语雪泥鸿爪是形容什么的?雪泥鸿爪什么意思?蚂蚁庄园2020年12月10日答案...

斑马线和斑马什么关系&#xff1f;大家都知道斑马和斑马线&#xff0c;但是两者之间有什么关系&#xff1f;蚂蚁庄园12月10日提到了这个问题&#xff0c;我们一起来看看正确答案吧。问题&#xff1a;斑马线和斑马有什么关系&#xff1f;答案&#xff1a;横线酷似斑马纹答案解析…

.Net 2.0里有一个有用的新功能:迭代器

下面内容节选至MSDN2005。迭代器&#xff08;C# 编程指南&#xff09; 迭代器是 C# 2.0 中的新功能。迭代器是方法、get 访问器或运算符&#xff0c;它使您能够在类或结构中支持 foreach 迭代&#xff0c;而不必实现整个 IEnumerable 接口。您只需提供一个迭代器&#xff0c;即…

js操作indexedDB增删改查示例

js操作indexedDB增删改查示例 if (indexedDB in window) {// 如果数据库不存在则创建&#xff0c;如果存在但是version更大&#xff0c;会自动升级不会复制原来的版本var req indexedDB.open("TestDB", 1);req.onupgradeneeded function(e) {var db req.result;//…

MySQL 服务器变量 数据操作DML-视图

原文:MySQL 服务器变量 数据操作DML-视图SQL语言的组成部分 常见分类&#xff1a; DDL&#xff1a;数据定义语言 DCL&#xff1a;数据控制语言&#xff0c;如授权 DML&#xff1a;数据操作语言 其它分类&#xff1a; 完整性定义语言&#xff1a;DDL的一部分功能约束约束&#x…

kafka内存不断增加_为什么 Kafka 能这么快的 6 个原因

无论 kafka 作为 MQ 也好&#xff0c;作为存储层也罢&#xff0c;无非就是两个功能(好简单的样子)&#xff0c;一是 Producer 生产的数据存到 broker&#xff0c;二是 Consumer 从 broker 读取数据。那 Kafka 的快也就体现在读写两个方面了&#xff0c;下面我们就聊聊 Kafka 快…

https网络编程——DNS域名解析获取IP地址

参考&#xff1a;DNS域名解析 地址&#xff1a;https://qingmu.blog.csdn.net/article/details/115825036?spm1001.2014.3001.5502 1、原理 我在在通过域名解析获取IP的过程中一般使用的是DNS域名解析。 DNS协议是一种应用层协议&#xff0c;他是基于UDP来实现的。 2、代码…

C#桌面时钟

使用C&#xff03;制作的桌面时钟&#xff0c;提供闹钟功能&#xff08;虽然很简陋&#xff09;、万年历功能&#xff08;包含农历&#xff09;源码&#xff1a;http://www.cnblogs.com/Files/shiweifu/MyClock.rar截图&#xff1a;适合初学者研究 转载于:https://www.cnblogs.…

小a与黄金街道(欧拉函数)/**模运算规则总结*/

链接&#xff1a;https://ac.nowcoder.com/acm/contest/317/D 来源&#xff1a;牛客网 题目描述 小a和小b来到了一条布满了黄金的街道上。它们想要带几块黄金回去&#xff0c;然而这里的城管担心他们拿走的太多&#xff0c;于是要求小a和小b通过做一个游戏来决定最后得到的黄金…

使用cvs或svn从sourceforge上获取开源项目的方法[转载]

著名开源软件网站&#xff08;www.sourceforge.net)上面的开源项目&#xff0c;大部分使用的管理工具为cvs或svn。这两种软件的代表客户端程序是wincvs和tortoiseSVN。1.cvsCVS (Concurrent Versions System) is a tool used by many software developers to manage changes wi…

堆栈认知——逆向IDA工具的基本使用

参考&#xff1a;逆向-IDA工具的基本使用 地址&#xff1a;https://qingmu.blog.csdn.net/article/details/118862881 目录1、文件的打开与关闭2、窗口介绍&#xff1a;图形 文本 其他窗口2.1、图形界面&#xff1a;2.2、文本界面&#xff1a;2.3、反汇编窗口2.4、 十六进制窗口…

jmeter中timeout值怎么设置_jMeter解决failed to respond Connection reset

通过以上可总结三种情况错误的情况如下&#xff1a;(以2000并发为例)----1&#xff1a;ideltimeout不设置&#xff0c;只设置connectionTimeout20s----一批接口中第一个接口肯定不会出现&#xff0c;因为他都是新建的tcp连接。----第二个接口容易出现RST&#xff0c;因为第一个…