/*
根据claris的 博客以及 beginend 的博客来写的 首先考虑如何求出最短路 可以从样例看出 路径是从边走到边的, 所以我们将边看作点 有共同端点的两边之间
互相连边, 边权为lcp。 这条边自己的花费计算要拆点, 拆成的两个点之间连原来的花费 这样跑最短路就可以啦 然而这样的做法有问题, 考虑边数最大可能是M^2切要求M^2个lca 显然不行 这里采用claris巨佬的方法 /*********beginend的题解*******
假如现在有n个节点a[1..n]要两两求lca,我们将其按dfs序排序,设h[i]=dep[lca(a[i],a[i+1])],根据后缀数组height数组的性质不难得到dep[lca(a[i],a[j])]=min(h[i]..h[j-1])。
那么我们可以枚举中间的每个h[i],i两边的点就可以至少花费h[i]的费用来互相访问。我们只要建立前缀虚点和后缀虚电来优化连边即刻。 */
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<iostream>
#define M 100200
#define ll long long
#define id1(x) x * 2 - 1
#define id2(x) x * 2
using namespace std;
int n,m, k, deep[M], dfn[M], size[M], fa[M], son[M], top[M], ls[M], inh[M], outh[M], inx[M], outx[M], pst[M];
int inp[M], outp[M], ins[M], outs[M], sz, head[M * ], cnt, tm, to[M << ], nxt[M << ], ver[M << ], a[M];
ll dis[M * ];
bool vis[M * ], in[M], out[M];
int read() {
int nm = , f = ;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -;
for(; isdigit(c); c = getchar()) nm = nm * + c -'';
return nm * f;
} void init() {
cnt = tm = ;
memset(head, , sizeof(head));
memset(ls, , sizeof(ls));
memset(inh, , sizeof(inh));
memset(outh, , sizeof(outh));
memset(son, , sizeof(son));
} void push(int vi, int vj, int wei) {
cnt++, to[cnt] = vj, ver[cnt] = wei, nxt[cnt] = head[vi], head[vi] = cnt;
if(cnt >= (M << )) {
puts("gg");
exit();
}
} void add(int vi, int vj) {
cnt++, to[cnt] = vj, nxt[cnt] = ls[vi], ls[vi] = cnt;
} void dfs1(int now) {
size[now] = ;
int maxx = ;
for(int i = ls[now]; i; i = nxt[i]) {
int vj = to[i];
deep[vj] = deep[now] + ;
fa[vj] = now;
dfs1(vj);
size[now] += size[vj];
if(size[vj] > maxx) maxx = size[vj], son[now] = vj;
}
} void dfs2(int now) {
dfn[now] = ++tm;
if(son[now]) {
top[son[now]] = top[now];
dfs2(son[now]);
}
for(int i = ls[now]; i; i = nxt[i]) {
int vj = to[i];
if(vj == son[now]) continue;
top[vj] = vj;
dfs2(vj);
}
} void spfa() {
for(int i = ; i <= sz; i++) dis[i] = 10000000000000000ll;
queue<int>q;
q.push();
dis[] = ;
vis[] = true;
while(!q.empty()) {
int op = q.front();
q.pop();
vis[op] = false;
for(int i = head[op]; i; i = nxt[i]) {
int vj = to[i];
if(dis[vj] > dis[op] + ver[i]) {
dis[vj] = dis[op] + ver[i];
if(!vis[vj]) {
vis[vj] = true;
q.push(vj);
}
}
}
}
} void dijk() {
for(int i = ; i <= sz; i++) dis[i] = 10000000000000000ll, vis[i] = ;
dis[] = ;
priority_queue<pair<int,int> > q;
q.push(make_pair(,));
while(!q.empty()) {
pair<int, int> now = q.top();
q.pop();
while(!q.empty() && vis[now.second]) now = q.top(), q.pop();
if(vis[now.second]) break;
int op = now.second;
vis[op] = true;
for(int i = head[op]; i; i = nxt[i]) {
int vj = to[i];
if(dis[vj] > dis[op] + ver[i]) {
dis[vj] = dis[op] + ver[i];
q.push(make_pair(-dis[vj],vj));
}
}
}
} int lca(int x, int y) {
while(top[x] != top[y]) {
if(deep[top[x]] < deep[top[y]]) swap(x, y);
x = fa[top[x]];
}
return deep[x] < deep[y] ? x : y;
} bool cmp(int x, int y) {
return dfn[pst[x]] < dfn[pst[y]];
} int main() {
int T = read();
while(T--) {
init();
n = read(), m = read(), k = read();
sz = m * ;
for(int i = ; i <= m; i++) {
int vi = read(), vj = read(), wei = read();
pst[i] = read();
push(id1(i), id2(i), wei);
inx[i] = inh[vj], inh[vj] = i, outx[i] = outh[vi], outh[vi] = i;
}
for(int i = ; i < k; i++) {
int vi = read(), vj = read();
read();
add(vi, vj);
}
dfs1(), top[] = fa[] = ;
dfs2();
for(int x = ; x <= n; x++) {
int a1 = ;
for(int i = inh[x]; i; i = inx[i]) a[++a1] = i, in[i] = ;
for(int i = outh[x]; i; i = outx[i]) a[++a1] = i, out[i] = ;
sort(a + , a + a1 + , cmp);
for(int i = ; i <= a1; i++) {
inp[i] = ++sz;
outp[i] = ++sz;
if(in[a[i]]) push(id2(a[i]), inp[i], );
if(out[a[i]]) push(outp[i], id1(a[i]), );
if(i > ) push(inp[i - ], inp[i], ), push(outp[i - ], outp[i], );
}
for(int i = a1; i >= ; i--) {
ins[i] = ++sz;
outs[i] = ++sz;
if(in[a[i]]) push(id2(a[i]), ins[i], );
if(out[a[i]]) push(outs[i], id1(a[i]), );
if(i < a1) push(ins[i + ], ins[i], ), push(outs[i + ], outs[i], );
}
for(int i = ; i < a1; i++) {
int lc = deep[lca(pst[a[i]], pst[a[i + ]])];
push(inp[i], outp[i + ], lc);
push(ins[i + ], outs[i], lc);
}
for(int i = ; i <= a1; i++) in[a[i]] = out[a[i]] = ;
}
for(int i = outh[]; i; i = outx[i]) push(, id1(i), );
//spfa();
dijk();
for(int x = ; x <= n; x++) {
ll mn = 10000000000000000ll;
for(int i = inh[x]; i; i = inx[i]) mn = min(mn, dis[id2(i)]);
cout << mn << "\n";
}
}
return ;
} /*
2
4 4 6
1 2 2 5
2 3 2 5
2 4 1 6
4 2 1 6
1 2 1
2 3 1
3 4 1
4 5 2
1 6 2 4 4 6
1 2 2 5
2 3 2 5
2 4 1 6
4 2 1 6
1 2 1
2 3 1
3 4 1
4 5 2
1 6 2 */

SDOI 2017 天才黑客的更多相关文章

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

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

  2. 影响Linux发展的四位天才黑客

    影响Linux发展的四位天才黑客 相信大家对 Linux 再熟悉不过了.我们都知道 Linux继承自 Unix,但其实他们上一代还有一个 Multics.从最早的 Multics 发展到最早版本的 L ...

  3. 【SDOI2017】天才黑客

    [SDOI2017]天才黑客 这题太神了. 先模Claris 大神的题解. 首先我们要将边转换为点.如果暴力连边就会有\(m^2\)的边,于是我们考虑优化建图. 难点在于快速得到两个边的串的\(lcp ...

  4. 【BZOJ4912】天才黑客(最短路,虚树)

    [BZOJ4912]天才黑客(最短路,虚树) 题面 BZOJ 洛谷 题解 \(Anson\)爷讲过的题目,然而我还是不会做 只有照着\(zsy\)的程序打我才会做....果然太弱了. 这道题目显然是把 ...

  5. 【LG3783】[SDOI2017]天才黑客

    [LG3783][SDOI2017]天才黑客 题面 洛谷 题解 首先我们有一个非常显然的\(O(m^2)\)算法,就是将每条边看成点, 然后将每个点的所有入边和出边暴力连边跑最短路,我们想办法优化这里 ...

  6. 【SDOI2017】天才黑客(前后缀优化建图 & 最短路)

    Description 给定一张有向图,\(n\) 个点,\(m\) 条边.第 \(i\) 条边上有一个边权 \(c_i\),以及一个字符串 \(s_i\). 其中字符串 \(s_1, s_2, \c ...

  7. 性感天才黑客乔治·霍兹George Hotz 17岁打脸乔布斯20岁搞疯索尼

    1.国内外著名黑客信息 1) 国外著名黑客 George Hotz 乔治·霍兹(George Hotz,1989年10月2日-),美国学生,2007年8月解锁苹果(Apple)iPhone手机,使得i ...

  8. SDOI 2017 Day1

    日期:2017-04-10 题解: 第一题: 题目大意:求fi(gcd(i,j))的乘积  i,j属于[1,1e6],数据组数1000组. 类别:套路题. 第二题:BZOJ原题. 题解:LCT套线段树 ...

  9. [SDOI 2017]新生舞会

    Description 题库链接 给你个 \(2\times N\) 的带权二分图,两个权值 \(a,b\) ,让你做匹配使得 \[\frac{\sum a}{\sum b}\] 最大. \(1\le ...

随机推荐

  1. I.MX6 Linux Serial Baud Rate hacking

    /******************************************************************************** * I.MX6 Linux Seri ...

  2. test20180828

    所有试题限制都为512MB,1Sec 总分230. 试题1 新的开始 [题目描述] 发展采矿业当然首先得有矿井, 小FF花了上次探险获得的千分之一的财富请人在岛上挖了n口矿井, 但他似乎忘记考虑的矿井 ...

  3. harbor helm 仓库使用

    harbor 已经支持helm 私服仓库了,还是比较方便的 安装 下载在线安装包 wget https://storage.googleapis.com/harbor-releases/release ...

  4. hasura graphql-engine v1.0.0-alpha25 的几个方便功能

    hasura graphql-engine 是一个很不错的graphql 引擎,但是我们的数据模型经常可能会有变动, 但是以前的版本对于这些的处理,官方的方式是删除元数据,重启server,都不是很好 ...

  5. 构建一个dbt 数据库适配器

    脚手架新的适配器 首先,将odbc适配器模板复制到同一目录中的新文件. 更新dbt / adapters / factory.py以将新适配器包含为类型.还要将类型添加到dbt / contracts ...

  6. stenciljs 学习四 组件装饰器

    stenciljs 可以方便的构建交互式组件 支持以下装饰器 component prop watch state method element component 说明 component 包含ta ...

  7. streamsets rest api 转换 graphql

    原理很简单,就是使用swagger api 生成schema 然后代理请求处理api 调用 参考项目 https://github.com/rongfengliang/streamsets-graph ...

  8. BatSendMail

    @echo off echo ==================================echo == Compress Files And Send Mail ==echo ======= ...

  9. Oracle 存储过程发送邮件

    CREATE OR REPLACE PROCEDURE PROCSENDEMAIL(P_TXT       VARCHAR2,                                      ...

  10. es 中的 Iterator

    for...in 遍历(当前对象及其原型上的)每一个属性名称,而 for...of 遍历(当前对象上的)每一个属性值 ES6 规定,默认的 Iterator 接口部署在数据结构的Symbol.iter ...