牛客网NOIP赛前集训营-提高组(第六场)-A-最长路[拓扑排序+hash+倍增]
题意
给定一个 \(n\) 点 \(m\) 边的边权非负的有向图,边有字符,求以每个点为开头的最长路字典序最小的路径 \(hash\) 值。
\(n,m\leq 10^6\)
分析
首先建反图拓扑排序后入度不为0的点的答案为 \(inf\) 。
在 \(dep\) 相同时,怎么比较两种转移的优劣?注意到建完反图之后可以通过判定两个转移第一个字典序不同的位置的大小,可以倍增\(+hash\) 实现。
总时间复杂度为 \(O(20*(n+m))\)。
代码
#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e6 + 7,mod=998244353;
int n,m,edc,hd=1,tl;
int head[N],ind[N],q[N],dep[N],to[N][21];
LL h[N][21],bin[N];
struct edge{
int last,to,c;
edge(){}edge(int last,int to,int c):last(last),to(to),c(c){}
}e[N*2];
void Add(int a,int b,int c){
e[++edc]=edge(head[a],b,c),head[a]=edc;++ind[b];
}
bool better(int x,int y){
for(int i=20;~i;--i)
if(h[x][i]==h[y][i]) x=to[x][i],y=to[y][i];
return h[x][0]<h[y][0];
}
void topo(){
rep(i,1,n) if(!ind[i]) q[++tl]=i,dep[i]=1;
for(;hd<=tl;++hd){
int u=q[hd];
rep(i,1,20){
to[u][i]=to[to[u][i-1]][i-1];
h[u][i]=(h[u][i-1]+h[to[u][i-1]][i-1]*bin[1<<i-1])%mod;
}
go(u){
if(dep[u]+1>dep[v]) dep[v]=dep[u]+1,to[v][0]=u,h[v][0]=e[i].c;
else if(dep[u]+1==dep[v]){
if(!to[v][0]||e[i].c<h[v][0]||(e[i].c==h[v][0]&&better(u,to[v][0])))
to[v][0]=u,h[v][0]=e[i].c;
}
if(--ind[v]==0) q[++tl]=v;
}
}
rep(i,1,n)
if(ind[i]) puts("Infinity");
else printf("%lld\n",29*h[i][20]%mod);
}
int main(){
n=gi(),m=gi();
for(int i=1,a,b,c;i<=m;++i){
a=gi(),b=gi(),c=gi();
Add(b,a,c);
}
bin[0]=1;
rep(i,1,N-1) bin[i]=1ll*bin[i-1]*29%mod;
topo();
return 0;
}
还有一种做法,将所有同层的点根据字典序优劣排序后转移到下一层,可以归纳证明。
#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e6 + 7,mod=998244353,inf=0x3f3f3f3f;
typedef pair<int,int> pii;pii f[N];
#define mp make_pair
int n,m,edc,hd=1,tl;
int head[N],ind[N],q[N],dep[N],rk[N],h[N];
struct edge{
int last,to,c;
edge(){}edge(int last,int to,int c):last(last),to(to),c(c){}
}e[N*2];
void Add(int a,int b,int c){
e[++edc]=edge(head[a],b,c),head[a]=edc;++ind[b];
}
vector<int>G[N];
bool cmp(int a,int b){
return f[a]<f[b];
}
void topo(){
rep(i,1,n) if(!ind[i]) q[++tl]=i,dep[i]=1,f[i]=mp(0,0);
else f[i]=mp(inf,inf);
for(;hd<=tl;++hd){
int u=q[hd];
G[dep[u]].pb(u);
go(u){
Max(dep[v],dep[u]+1);
if(--ind[v]==0) q[++tl]=v;
}
}
rep(j,1,n){
for(auto u:G[j])
go(u)if(dep[u]+1==dep[v]){
if(mp(e[i].c,rk[u])<f[v]){
f[v]=mp(e[i].c,rk[u]);
h[v]=(1ll*h[u]*29+e[i].c)%mod;
}
}
sort(G[j+1].begin(),G[j+1].end(),cmp);
rep(i,0,(int)G[j+1].size()-1) rk[G[j+1][i]]=i;
}
rep(i,1,n)
if(ind[i]) puts("Infinity");
else printf("%lld\n",1ll*29*h[i]%mod);
}
int main(){
n=gi(),m=gi();
for(int i=1,a,b,c;i<=m;++i){
a=gi(),b=gi(),c=gi();
Add(b,a,c);
}
topo();
return 0;
}
牛客网NOIP赛前集训营-提高组(第六场)-A-最长路[拓扑排序+hash+倍增]的更多相关文章
- 牛客网NOIP赛前集训营-普及组(第二场)和 牛客网NOIP赛前集训营-提高组(第二场)解题报告
目录 牛客网NOIP赛前集训营-普及组(第二场) A 你好诶加币 B 最后一次 C 选择颜色 D 合法括号序列 牛客网NOIP赛前集训营-提高组(第二场) A 方差 B 分糖果 C 集合划分 牛客网N ...
- 牛客网NOIP赛前集训营-提高组(第二场)A 方差
链接:https://www.nowcoder.com/acm/contest/173/A来源:牛客网 题目描述 一个长度为 m 的序列 b[1...m] ,我们定义它的方差为 ,其中 表示序列的平 ...
- [牛客网NOIP赛前集训营-提高组(第一场)]C.保护
链接:https://www.nowcoder.com/acm/contest/172/C来源:牛客网 题目描述 C国有n个城市,城市间通过一个树形结构形成一个连通图.城市编号为1到n,其中1号城市为 ...
- 牛客网NOIP赛前集训营-提高组(第一场)
牛客的这场比赛感觉真心不错!! 打得还是很过瘾的.水平也比较适合. T1:中位数: 题目描述 小N得到了一个非常神奇的序列A.这个序列长度为N,下标从1开始.A的一个子区间对应一个序列,可以由数对[l ...
- 比赛总结——牛客网 NOIP赛前集训营提高组模拟第一场
第一场打的很惨淡啊 t1二分+前缀最小值没想出来,20分的暴力也挂了,只有10分 t2数位dp,调了半天,结果因为忘了判0的特殊情况WA了一个点,亏死 t3emmmm.. 不会 imone说是DSU ...
- 牛客网NOIP赛前集训营-提高组(第一场)B 数数字
数数字 思路: 数位dp 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...
- 牛客网NOIP赛前集训营-提高组(第一场)A 中位数
中位数 思路: 二分答案 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...
- 牛客网NOIP赛前集训营 提高组 第5场 T2 旅游
[题解] 我们可以发现不在最小生成树上的边一定不能多次经过,因为一条不在最小生成树上的边(u,v)的边权比最小生成树上(u,v)之间的路径更长,选择不在最小生成树上的边一定不划算. 我们还需要确定最小 ...
- 牛客网NOIP赛前集训营-提高组(第四场)游记
牛客网NOIP赛前集训营-提高组(第四场)游记 动态点分治 题目大意: \(T(t\le10000)\)组询问,求\([l,r]\)中\(k(l,r,k<2^{63})\)的非负整数次幂的数的个 ...
- 牛客网NOIP赛前集训营-提高组(第四场)B区间
牛客网NOIP赛前集训营-提高组(第四场)B区间 题目描述 给出一个序列$ a_1 \dots a_n$. 定义一个区间 \([l,r]\) 是好的,当且仅当这个区间中存在一个 \(i\),使得 ...
随机推荐
- 阿里云MaxCompute被Forrester评为全球云端数据仓库领导者
参考消息网3月19日报道 日前,全球权威调研机构佛瑞斯特研究公司(Forrester)发布<2018年一季度云端数据仓库>报告.报告对大数据服务商的主要功能.区域表现.细分市场和典型客户等 ...
- 绕过CDN查找网站真实IP方法收集
方法1很简单,使用各种多地 ping 的服务,查看对应 IP 地址是否唯一,如果不唯一多半是使用了CDN, 多地 Ping 网站有: http://ping.chinaz.com/ http://pi ...
- 026.2 网络编程 UDP聊天
实现,通过socket对象 ##############################################################需求建立UDP发送端:###思路:1.建立可以实 ...
- 关于Oracle11g R2的学习笔记
进来由于工作需要开始有SQLServer向Oracle转型学习,想把学习写到这里作为记录和备忘. Oracle 11g R2下面都简称:Oracle 第一:Oracle的安装 在安装过程没有 ...
- sqooq同步mysql tinyint类型到hive的一个诡异问题
sqoop job运行完成之后,发现为tinyint类型的一类始终没有值,经检查发现上游mysql有值,再查看hdfs文件,发现这列被抓换为了boolean类型 搜索一下发现有人碰到过了,以下原文来自 ...
- Hadoop学习之路(十)HDFS API的使用
HDFS API的高级编程 HDFS的API就两个:FileSystem 和Configuration 1.文件的上传和下载 package com.ghgj.hdfs.api; import org ...
- virtualbox+vagrant学习-2(command cli)-15-vagrant resume命令
Resume 格式: vagrant resume [vm-name] 这将恢复先前挂起的vagrant托管计算机,可能与suspend命令一起使用. 默认情况下,配置的预配置程序在运行该命令时将不再 ...
- virtualbox+vagrant学习-2(command cli)-17-vagrant ssh命令
SSH 格式: vagrant ssh [options] [name|id] [-- extra ssh args] 这将SSH导入正在运行的vagrant机器,并允许你访问机器的shell. us ...
- mariadb密码问题
错误信息: Mysql:ERROR 1698 (28000): Access denied for user 'root'@'localhost' 解决办法: sudo cat /etc/mysql/ ...
- hive遇到的问题以及解决办法
hive java.lang.ClassNotFoundException: Class org.apache.hive.hcatalog.data.JsonSerDe not found hadoo ...