http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1815

tarjan缩点后在DAG上递推即可。

每个点维护所有根到它的路径上的值的最大值,严格次大值,最大的“根到这个点的一条路径中的严格次大值”(也就是答案)。

注意所有根到它的路径上的值的严格次大值不是答案。

时间复杂度\(O(n)\)。

#include<cstdio>
#include<bitset>
#include<cstring>
#include<algorithm>
using namespace std; const int N = 400003;
const int M = 2000003; struct node {int nxt, to;} E[M], E2[M], E3[M];
int cnt = 0, cnt3 = 0, point[N], point2[N], cur[N], du[N], point3[N]; void ins(int u, int v) {E[++cnt] = (node) {point[u], v}; point[u] = cnt;}
void ins2(int u, int v) {
E2[++cnt] = (node) {point2[u], v}; point2[u] = cnt;
E3[++cnt3] = (node) {point3[v], u}; point3[v] = cnt3;
} bitset <N> inst;
int dfn[N], low[N], tot = 0, a[N], sta[N], statop, st[N], top, bel[N], n, m, q, s, fa[N]; void tarjan(int x) {
st[top = 1] = x; statop = 0;
while (top) {
int u = st[top];
if (!dfn[u]) {
dfn[u] = low[u] = ++cnt;
sta[++statop] = u;
inst[u] = 1;
}
if (cur[u]) {
int v = E[cur[u]].to;
if (!dfn[v]) fa[st[++top] = v] = u;
else if (inst[v]) low[u] = min(low[u], dfn[v]);
cur[u] = E[cur[u]].nxt;
} else {
low[fa[u]] = min(low[fa[u]], low[u]);
if (dfn[u] == low[u]) {
++tot;
while (sta[statop] != u) {
inst[sta[statop]] = 0;
bel[sta[statop]] = tot;
--statop;
}
inst[u] = 0;
bel[u] = tot;
--statop;
}
--top;
}
}
} bitset <N> vis;
int max1[N], max2[N], max3[N], qu[N], A[4]; void BFS() {
int p = 0, q = 1;
vis[qu[1] = bel[s]] = 1;
while (p != q) {
int u = qu[++p];
for (int i = point2[u]; i; i = E2[i].nxt) {
int v = E2[i].to;
++du[v];
if (!vis[v]) {
vis[v] = 1;
qu[++q] = v;
}
}
} p = 0; q = 1; qu[1] = bel[s];
while (p != q) {
int u = qu[++p];
for (int i = point3[u]; i; i = E3[i].nxt) {
int v = E3[i].to;
if (vis[v]) {
if (max1[v] > max1[u]) {max3[u] = max1[u]; max1[u] = max1[v];}
else if (max1[v] < max1[u] && max1[v] > max3[u]) max3[u] = max1[v];
if (max3[v] > max1[u]) {max3[u] = max1[u]; max1[u] = max3[v];}
else if (max3[v] < max1[u] && max3[v] > max3[u]) max3[u] = max3[v];
}
}
for (int i = point2[u]; i; i = E2[i].nxt) {
int v = E2[i].to;
max2[v] = max(max2[v], max2[u]);
if (max1[u] != max1[v]) max2[v] = max(max2[v], min(max1[u], max1[v]));
else max2[v] = max(max2[v], max(max3[u], max3[v]));
if (--du[v] == 0) qu[++q] = v;
}
}
} int main() {
scanf("%d%d%d%d", &n, &m, &q, &s);
for (int i = 1; i <= n; ++i)
scanf("%d", a + i);
int u, v;
for (int i = 1; i <= m; ++i) {
scanf("%d%d", &u, &v);
ins(u, v);
} cnt = 0;
for (int i = 1; i <= n; ++i)
cur[i] = point[i], max1[i] = max2[i] = -1;
for (int i = 1; i <= n; ++i)
if (!dfn[i]) tarjan(i); cnt = 0;
for (int i = 1; i <= n; ++i)
for (int j = point[i]; j; j = E[j].nxt)
if (bel[i] != bel[E[j].to])
ins2(bel[i], bel[E[j].to]); for (int i = 1; i <= n; ++i) {
int t = bel[i];
if (a[i] > max1[t]) max2[t] = max1[t], max1[t] = a[i];
else if (a[i] < max1[t] && a[i] > max2[t]) max2[t] = a[i];
}
for (int i = 1; i <= tot; ++i) max3[i] = max2[i]; BFS(); for (int i = 1; i <= q; ++i) {
scanf("%d", &u);
if (!vis[bel[u]]) printf("-1 ");
else if (max2[bel[u]] == -1) printf("0 ");
else printf("%d ", max2[bel[u]]);
}
return 0;
}

【51Nod 1815】【算法马拉松 23】调查任务的更多相关文章

  1. 51Nod 算法马拉松23 开黑记

    惨啊……虽然开了半天黑,但是还是被dalao们踩了…… 第二次开黑,还是被卡在rank20了,我好菜啊……= = 写一写比赛经过吧…… 看到题之后习惯性都打开,A~D看上去似乎并没有什么思路,F应该是 ...

  2. 【51Nod 1756】【算法马拉松 23】谷歌的恐龙

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1765 设答案为\(X\). 则\[X=\frac{m}{n}\times ...

  3. 随便玩玩系列之一:SPOJ-RNG+51nod 算法马拉松17F+51nod 1034 骨牌覆盖v3

    先说说前面的SPOJ-RNG吧,题意就是给n个数,x1,x2,...,xn 每次可以生成[-x1,x1]范围的浮点数,把n次这种操作生成的数之和加起来,为s,求s在[A,B]内的概率 连续形的概率 假 ...

  4. 51NOD 算法马拉松8

    题目戳这里:51NOD算法马拉松8 某天晚上kpm在玩OSU!之余让我看一下B题...然后我就被坑进了51Nod... A.还是01串 水题..怎么乱写应该都可以.记个前缀和然后枚举就行了.时间复杂度 ...

  5. 51nod 算法马拉松 34 Problem D 区间求和2 (FFT加速卷积)

    题目链接  51nod 算法马拉松 34  Problem D 在这个题中$2$这个质数比较特殊,所以我们先特判$2$的情况,然后仅考虑大于等于$3$的奇数即可. 首先考虑任意一个点对$(i, j)$ ...

  6. 51Nod 算法马拉松21(迎新年)

    这次打算法马拉松是在星期五的晚上,发挥还算正常(废话,剩下的题都不会= =). 讲讲比赛经过吧. 8:00准时发题,拿到之后第一时间开始读. A配对,看上去像是二分图最大权匹配,一看范围吓傻了,先跳过 ...

  7. 推荐一个算法编程学习中文社区-51NOD【算法分级,支持多语言,可在线编译】

    最近偶尔发现一个算法编程学习的论坛,刚开始有点好奇,也只是注册了一下.最近有时间好好研究了一下,的确非常赞,所以推荐给大家.功能和介绍看下面介绍吧.首页的标题很给劲,很纯粹的Coding社区....虽 ...

  8. 51Nod 算法马拉松15 记一次悲壮而又开心的骗分比赛

    OwO 故事的起源大概是zcg前天发现51Nod晚上有场马拉松,然后他就很开心的过去打了 神奇的故事就开始了: 晚上的时候我当时貌似正在写线段树?然后看见zcg一脸激动告诉我第一题有九个点直接输出B就 ...

  9. 51Nod 算法马拉松22 开黑记

    这是一场惨烈的开黑大战,始于全机房开黑指望刷进rank前十拿钱的壮志,终于被各路神犇怒踩成rank20,差点200点头盾不保的落魄,想起将近一年前ad和zcg等学长挤进rank10的壮举,不由得唏嘘, ...

随机推荐

  1. 前端开发必知必会:CSS Position 全解析

    此文根据Steven Bradley的<How Well Do You Understand CSS Positioning?>所译,整个译文带有我自己的理解与思想,如果译得不好或不对之处 ...

  2. mybatis错误总结

    1:传递多个参数失败   Parameter 'username' not found. Available parameters are [0, 1, param1, param2] dao层错误写 ...

  3. 【leetcode 简单】第二十题 合并两个有序数组

    给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m 和 n. ...

  4. 1030 大数进制转换(51Nod + JAVA)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1030 题目: 代码实现如下: import java.mat ...

  5. javaScript操作数组的常用方法

    map(映射), reduce(规约), forEach(遍历), filter(过滤),它们都是高阶函数,都是以传入不同的函数来以不同的方式操作数组元.ie都不支持 判断是否为数组 Array.is ...

  6. 修改ecshop后台的管理菜单

    ecshop后台菜单如何去修改,下面ecshop开发中心如何去修改 首先先打开后台菜单项相关文件: admin\includes\inc_menu.php languages\zh_cn\admin\ ...

  7. 一个Servlet处理增删改查的方法

    处理的思路是在servlet中定义不同的增删改查方法,页面请求 的时候携带请求的参数,根据参数判断调用不同的方法. package cn.xm.small.Servlet; import java.i ...

  8. s3c6410下移植sqlite3.7.8

    http://blog.chinaunix.NET/uid-30441-id-2133838.html 1.下载源代码http://www.sqlite.org/download.html 2.tar ...

  9. 190.Reverse Bits---位运算

    题目链接:https://leetcode.com/problems/reverse-bits/description/ 题目大意:将数值的二进制反转. 法一(借鉴):由于是无符号32位整型,当二进制 ...

  10. C#窗口矩形区域着色

    C#写的一个GUI窗口,有几百个矩形区域.每个矩形区域的颜色随时都可能改变,并且多次改变. 我放弃使用label绘制矩形,因为效果不好.拖控件的界面使用power packs中的rectanglesh ...