【SDOI2017】天才黑客




这题太神了。

先模Claris 大神的题解。

首先我们要将边转换为点。如果暴力连边就会有\(m^2\)的边,于是我们考虑优化建图。

难点在于快速得到两个边的串的\(lcp\),也就是\(trie\)树上的\(lca\)。我们将一堆点按\(dfs\)序排序,然后\(a\)到\(b\)的\(lca\)就是排序后\(min\{lca(a,a+1),lca(a+1,a+2)...lca(b-1,b)\}\),这里的\(min\)是深度最小。

对于原图上的点\(i\),我们就将所有的边按\(dfs\)序拍好序,再复制一倍的虚点,相邻的实点和虚点连权值为\(0\)的边。每个实点向下一个点对应的虚点连权值为\(dep_{lca}\)的边。

然后还要反方向建相同的边,不过不能建在一张图上。

这道题中关于处理一堆点两两之间\(lca\)的方法值得掌握。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 400005using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}int n,m,k;
int tot,TOT;
int w[N],t[N];
ll dis[N];
ll ans[N];
vector<int>st[N];
vector<int>e[N];
struct road {int to,next;ll c;
}s[N*15];
int h[N],cnt;
void add(int i,int j,int c) {s[++cnt]=(road) {j,h[i],c};h[i]=cnt;}int id,dfn[N];
void Init() {cnt=0;id=0;memset(h,0,sizeof(h));memset(t,0,sizeof(t));memset(w,0,sizeof(w));memset(dis,0x3f,sizeof(dis));for(int i=1;i<=k;i++) e[i].clear();for(int i=1;i<=n;i++) st[i].clear();
}int dep[N];
int fa[N][20];bool cmp(int a,int b) {return dfn[t[a]]<dfn[t[b]];}
bool cmp2(int a,int b) {return dfn[t[a]]>dfn[t[b]];}int lca(int a,int b) {if(dep[a]<dep[b]) swap(a,b);for(int i=16;i>=0;i--)if(fa[a][i]&&dep[fa[a][i]]>=dep[b])a=fa[a][i];if(a==b) return a;for(int i=16;i>=0;i--)if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];return fa[a][0];
}void dfs(int v) {dfn[v]=++id;for(int i=1;i<=16;i++) fa[v][i]=fa[fa[v][i-1]][i-1];for(int i=0;i<e[v].size();i++) {int to=e[v][i];dep[to]=dep[v]+1;fa[to][0]=v;dfs(to);}
}void build() {for(int i=1;i<=n;i++) {sort(st[i].begin(),st[i].end(),cmp);for(int j=0;j<st[i].size()-1;j++) {add(st[i][j],st[i][j+1],0);add(st[i][j]+tot,st[i][j+1]+tot,0);add(st[i][j],st[i][j+1]+tot,dep[lca(t[st[i][j]],t[st[i][j+1]])]);}reverse(st[i].begin(),st[i].end());for(int j=0;j<st[i].size()-1;j++) {add(st[i][j]+TOT,st[i][j+1]+TOT,0);add(st[i][j]+tot+TOT,st[i][j+1]+tot+TOT,0);add(st[i][j]+TOT,st[i][j+1]+tot+TOT,dep[lca(t[st[i][j]],t[st[i][j+1]])]);}}
}struct node {int v,d;node() {v=0,d=0;}node(int a,int b) {v=a,d=b;}bool operator <(const node &a)const {return d>a.d;}
};
priority_queue<node>q;bool vis[N];
void dij() {memset(vis,0,sizeof(vis));while(!q.empty()) {node tem=q.top();q.pop();int v=tem.v;if(vis[v]) continue ;vis[v]=1;for(int i=h[v];i;i=s[i].next) {int to=s[i].to;if(vis[to]) continue ;if(dis[to]>dis[v]+s[i].c) {dis[to]=dis[v]+s[i].c;q.push(node(to,dis[to]));}}}
}int main() {int T=Get();while(T--) {n=Get(),m=Get(),k=Get();Init();tot=m<<1,TOT=tot<<1;int a,b,c,d;for(int i=1;i<=m;i++) {a=Get(),b=Get(),c=Get(),d=Get();t[i]=t[i+m]=d;w[i]=w[i+TOT]=c;st[b].push_back(i);st[a].push_back(i+m);add(i+m+tot,i,w[i]);add(i+m+tot+TOT,i,w[i]);add(i+m+tot,i+TOT,w[i]);add(i+m+tot+TOT,i+TOT,w[i]);}for(int i=1;i<k;i++) {a=Get(),b=Get(),c=Get();e[a].push_back(b);}dfs(1);build();for(int i=0;i<st[1].size();i++) {if(st[1][i]>m) {dis[st[1][i]-m]=dis[st[1][i]-m+TOT]=w[st[1][i]-m];q.push(node(st[1][i]-m,w[st[1][i]-m]));q.push(node(st[1][i]-m+TOT,w[st[1][i]-m]));}}dij();memset(ans,0x3f,sizeof(ans));for(int i=1;i<=n;i++) {for(int j=0;j<st[i].size();j++)if(st[i][j]<=m) {ans[i]=min(ans[i],min(dis[st[i][j]],dis[st[i][j]+TOT]));}}for(int i=2;i<=n;i++) cout<<ans[i]<<"\n";}return 0;
}

转载于:https://www.cnblogs.com/hchhch233/p/10468062.html

【SDOI2017】天才黑客相关推荐

  1. [LOJ#2270][BZOJ4912][SDOI2017]天才黑客

    [LOJ#2270][BZOJ4912][SDOI2017]天才黑客 试题描述 SD0062 号选手小 Q 同学为了偷到 SDOI7012 的试题,利用高超的黑客技术潜入了 SDOI 出题组的内联网的 ...

  2. [SDOI2017]天才黑客

    传送门 Description 给出一张带边权的有向图,每个边都上都有一个字符串(给出对应Trie树上的节点),一条路径的长度为路径上的边权之和+相邻两条边的字符串的lcp长度之和. 求从1到其它节点 ...

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

    容易想到把边当成点重建图跑最短路.将每条边拆成入边和出边,作为新图中的两个点,由出边向入边连边权为原费用的边.对于原图中的每个点,考虑由其入边向出边连边.直接暴力两两连边当然会被卡掉,注意到其边权是t ...

  4. 天才黑客 Flanker 疑因拒绝做黑客被拼多多强行辞退

    整理 | 王晓曼 出品 | 程序人生 (ID:coder _life) 1月12日,"如何看待天才黑客Flanker疑因拒绝做黑客攻击业务,被拼多多强行辞退,错失上亿股票?"的话题 ...

  5. 拼多多再添新瓜!15 岁上浙大、22 岁获世界冠军的天才黑客 Flanker 疑因拒绝违法攻击被强制开除...

    拼多多又出事了. 近日,拼多多因员工猝死,跳楼自杀.开除员工等事一直游走在舆论的风口浪尖,而前拼多多安全大佬 Flanker 离职的故事也被扒了出来,成为了拼多多舆论的又一风暴点. 1 月 12 日早 ...

  6. GitHub 热榜:天才黑客开源新项目,不到 1000 行代码,1400 Star!

    点击上方"Github爱好者社区",选择星标 回复"资料",获取小编整理的一份资料 来自机器之心 在深度学习时代,谷歌.Facebook.百度等科技巨头开源了多 ...

  7. 图森计划裁员25%/ 特斯拉被曝将冻结招聘/ 天才黑客Geohot从推特辞职…今日更多新鲜事在此...

    日报君 发自 凹非寺 量子位 | 公众号 QbitAI 大家好,今天是12月22日星期四,距离周末还有两天,距离圣诞还有三天. 今天科技圈都有哪些大事发生,快来和日报君一起康康- 图森计划裁员25% ...

  8. 不到1000行代码,GitHub 1400星,天才黑客开源深度学习框架tinygrad

    来源:机器之心 本文约2000字,建议阅读5分钟 最近,天才黑客 George Hotz 开源了一个小型深度学习框架 tinygrad,兼具 PyTorch 和 micrograd 的功能.tinyg ...

  9. 干一个月就跑了!“天才黑客”George Hotz从推特离职

    推特实习33天,'天才黑客'George Hotz宣布辞职.他感谢马斯克给的机会,但表示在这儿'做不成什么事'. 北京时间12月21日,因开发iOS越狱和对PlayStation 3进行逆向工程而名声 ...

最新文章

  1. Android中的Menu和对话框形式的Activity
  2. 大一计算机课程ppt作业,大学生计算机基础作业PPT.ppt
  3. oracle的all函数,oracle函数 MIN([distinct|all]x)
  4. 转结构体_golang处理gb2312转utf8编码的问题
  5. walletconnect
  6. cocos2d js调用java_【cocos2d-js官方文档】二十四、如何在android平台上使用js直接调用Java方法...
  7. 使用nohup在后台运行scp
  8. POJ_2593最大两不想交子段和问题
  9. 角速度求积分能得到欧拉角吗_一个有趣的反常积分问题
  10. android 仿微信朋友圈 评论,2020年android 仿微信朋友圈 评论
  11. NPAPI插件开发详细记录:插件开发入门
  12. Cisco2811路由器的首次接触
  13. 推荐一个视频播放器potplayer
  14. 网站被黑中毒WebShell木马的解决方案
  15. chrome模拟手机浏览器方法
  16. SVG实现圆形进度条
  17. HIVE学习系列——Hive操作
  18. 甘肃省全国计算机等级考试(NCRE)报名
  19. 什么是SVN(Subversion)?为什么要用SVN?
  20. 常见电路分析十:万用表自动关机的原理

热门文章

  1. CSS hack:针对IE6,IE7,IE8,IE9,firefox显示不同效果
  2. Redhat安装gtk2.0和pkg-config
  3. 【转载】VMware安装CentOS7时忘记装图形化界面——如何补装GNOME
  4. C语言—用结构体指针给数组赋值(结构体指针指向字符串,给字符串赋值)
  5. javaScript tips —— z-index 对事件机制的影响
  6. Unity3d 简单的小球沿贝塞尔曲线运动(适合场景漫游使用)
  7. 失眠——耳部按摩(组图)
  8. LeetCode(1)Two Sum
  9. [Objective-C] Copy 和 MutableCopy
  10. MVC通过ViewBag动态生成Html输出到View