/*
根据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. java 百分比显示Double类型数值

    DecimalFormat percent = new DecimalFormat("0.00%"); completed_num = (double) involvedTask_ ...

  2. Mat类型at问题-opencv-bug调试

    前言 调试程序的过程中,opencv创建矩阵之后对其赋值出现错误: Mat m = Mat::zeros(1, featureLen, CV_32FC1); Mat data = Mat::zeros ...

  3. uva1482:Playing With Stones (SG函数)

    题意:有N堆石子,每次可以取一堆的不超过半数的石子,没有可取的为输. 思路:假设只有一堆,手推出来,数量x可以表示为2^p-1形式的必输. 但是没什么用,因为最后要的不是0和1,而是SG函数:所以必输 ...

  4. xdoj 1044---炸红花 (话说 小时候经常玩这个被虐。。。。qwq)

    // 我真的好笨 只会枚举 话说那个ac的370b到底是怎么做的 /(ㄒoㄒ)/~~ #include <iostream> #include <algorithm> usin ...

  5. PAT天梯:L1-019. 谁先倒

    L1-019. 谁先倒 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 划拳是古老中国酒文化的一个有趣的组成部分.酒桌上两人划拳 ...

  6. ZOJ 3551 吸血鬼 概率DP

    解题报告链接: http://www.cnblogs.com/183zyz/archive/2012/09/13/2683524.html 做法:设当有i个吸血鬼时变成n个吸血鬼的天数的数学期望为dp ...

  7. 手把手图文教你eclipse下如何配置tomcat

    很多初学,尤其自学JavaWeb的朋友首次在eclipse下配置tomcat时,总会有种难下手的感觉,在此,笔者通过图文解说的方法,最直观的向大家演示一遍该配置过程,希望对大家有所帮助. 注:本文是建 ...

  8. setsockopt IP_ADD_MEMBERSHIP error!No such device的解决方案

    /mnt # ./onvifserver Happytime onvif server version 2.6Onvif server running at 192.168.1.10:8000crea ...

  9. Apache关闭VirtualHost的Log日志记录

    有时我们的apache产生的日志是超大的并且 没什么用处,这时我们就可以关闭了,关闭apache日志很简单,直接ErrorLog off或 # CustomLog即可. Web server(ex: ...

  10. C#之设计模式之六大原则

    一.单一职责原则 原文链接:http://blog.csdn.net/lovelion/article/details/7536542 单一职责原则是最简单的面向对象设计原则,它用于控制类的粒度大小. ...