从若干个数中选出最大的任意两数取模之后的结果

严格次大值

对于此题

首先缩点

然后拓扑排序

维护到达每个点的最大值与严格次大值

感觉思路与代码都OK啊

then....

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <ctime> using namespace std; #define LL long long #define gc getchar()
inline int read() {int x = ; char c = gc; while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc; return x;}
inline LL read_LL() {LL x = ; char c = gc; while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc; return x;}
#undef gc const int N = 4e5 + , M = 2e6 + ;
int n, m, S, Q;
int A[N]; int Dfn[N], Low[N], Belong[N], Beljs, Tim;
bool vis[N];
int Stack[N], topp; pair <int, int> Pair[N];
struct Node {int u, v, nxt;} G[M];
int head1[N], cnt; inline void Link(int u, int v) {G[++ cnt].v = v; G[cnt].nxt = head1[u]; head1[u] = cnt;} void Tarjan(int u) {
Dfn[u] = Low[u] = ++ Tim;
vis[u] = ;
Stack[++ topp] = u;
for(int i = head1[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(!Dfn[v]) {
Tarjan(v);
Low[u] = min(Low[u], Low[v]);
} else if(vis[v]) Low[u] = min(Low[u], Low[v]);
}
if(Low[u] == Dfn[u]) {
int Max = , CMax = ;
Max = A[u];
vis[u] = ; Belong[u] = ++ Beljs;
Pair[Beljs].first = A[u]; Pair[Beljs].second = -;
while(Stack[topp] != u) {
int a = Stack[topp];
vis[a] = ;
Belong[a] = Beljs;
topp --;
if(A[a] > Max) {CMax = Max, Max = A[a];}
else if(A[a] != Max) CMax = max(CMax, A[a]);
Pair[Beljs] = make_pair(Max, CMax);
} topp --;
}
} Node E[M];
int head2[N], Du[N]; inline void ReLink(int u, int v) {Du[v] ++; E[++ cnt].v = v; E[cnt].nxt = head2[u]; head2[u] = cnt;} int use[N]; void Rebuild() {
for(int i = ; i <= Beljs; i ++) head2[i] = -;
cnt = ;
for(int u = ; u <= n; u ++)
for(int i = head1[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(Belong[u] != Belong[v] && use[Belong[v]] != u) {
use[Belong[v]] = u;
// cout << Belong[u] << " " << Belong[v] << "\n";
ReLink(Belong[u], Belong[v]);
}
}
} int Que[N]; bool beuse[N]; void Topsort() {
int h = , t = ;
// for(int i = 1; i <= Beljs; i ++) if(Du[i] == 0) Que[++ t] = i;
Que[++ t] = Belong[S];
while(h <= t) {
int topu = Que[h ++];
beuse[topu] = ;
for(int i = head2[topu]; ~ i; i = E[i].nxt) {
int v = E[i].v;
Du[v] --;
if(Du[v] == ) Que[++ t] = v;
int B[];
// cout << Pair[topu].first << " " << Pair[topu].second << " " << Pair[v].first << " " << Pair[v].second << "\n";
B[] = Pair[topu].first, B[] = Pair[topu].second, B[] = Pair[v].first, B[] = Pair[v].second;
sort(B + , B + );
Pair[v].first = B[];
int j = ;
while(B[j] == B[]) j --;
Pair[v].second = B[j];
}
}
} int main() {
// srand(time(0) - 99999);
// freopen("gg.in", "r", stdin);
// freopen("gg.out", "w", stdout);
n = read(), m = read(), Q = read(), S = read();
for(int i = ; i <= n; i ++) A[i] = read();
for(int i = ; i <= n; i ++) head1[i] = -;
for(int i = ; i <= m; i ++) {
int u = read(), v = read();
Link(u, v);
}
for(int i = ; i <= n; i ++)
if(!Dfn[i])
Tarjan(i);
// for(int i = 1; i <= Beljs; i ++) {
// cout << Pair[i].first << " " << Pair[i].second << "\n";
// }
// return 0;
Rebuild();
// for(int i = 1; i <= Beljs; i ++) {
// for(int j = head2[i]; ~ j; j = E[j].nxt) {
// int v = E[j].v;
// cout << i << " " << v << "\n";
// }
// }
Topsort();
for(int i = ; i <= Q; i ++) {
int a = read();
if(beuse[Belong[a]] == ) cout << - << " ";
else cout << Pair[Belong[a]].second << " ";
// if(ans == 0) cout << -1 << " ";
// cout << ans << " ";
}
return ;
}
/*
8 10 5 1
5 5 5 7 5 5 5 5
1 2
2 3
3 1
3 4
5 1
6 5
1 6
6 8
8 7
7 6
1 2 3 4 5
*/

*51nod 1815的更多相关文章

  1. 【51Nod 1815】【算法马拉松 23】调查任务

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1815 tarjan缩点后在DAG上递推即可. 每个点维护所有根到它的路径 ...

  2. 51Nod 1815 调查任务

    发现绍一的人很喜欢做51nod,不得不说这还是一个很全能的良心OJ 但是做的这道题就一点都不良心了,简直是毒瘤,调了一早上 首先我们考虑让一条路径的\(a_x\ mod\ a_y\)的值最大,我们简单 ...

  3. 51nod图论题解(4级,5级算法题)

    51nod图论题解(4级,5级算法题) 1805 小树 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 她发现她的树的点上都有一个标号(从1到n),这些树都在空 ...

  4. 【51Nod 1244】莫比乌斯函数之和

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1244 模板题... 杜教筛和基于质因子分解的筛法都写了一下模板. 杜教筛 ...

  5. 51Nod 1268 和为K的组合

    51Nod  1268  和为K的组合 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使 ...

  6. 51Nod 1428 活动安排问题

    51Nod   1428  活动安排问题 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1428 1428 活 ...

  7. 51Nod 1278 相离的圆

    51Nod 1278 相离的圆 Link: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1278 1278 相离的圆 基 ...

  8. 【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1501 dp求出环状不连续的前缀和,剩下东西都可以算出来,比较繁琐. 时间 ...

  9. 【51Nod 1622】【算法马拉松 19C】集合对

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1622 简单题..直接暴力快速幂 #include<cstdio&g ...

随机推荐

  1. Android--DES加密

    Base64.java import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputS ...

  2. thrift原理与架构

    是什么: 一个RPC框架.

  3. mysql授权单个表权限

    mysql> create user haochengtest@'%' identified by 'haocheng.123'; Query OK, 0 rows affected (0.01 ...

  4. 单例模式详解以及需要注意的地方(Singleton)

    单例模式,顾名思义,就是在Java程序中只有唯一一个实例,这样做的好处是可以在不需要多个实例的对象采用单例模式可以节省内存,否则会造成不必要的内存浪费.单例模式的定义为:保证一个类只有一个实例,自己可 ...

  5. 【转载】Windows检测到IP地址冲突

    今天在使用电脑的过程中,突然弹出个提示,Windows检测到IP地址冲突,此网络中的另一台计算机与该计算机的IP地址相同.联系你的网络管理员解决此问题,有关详细信息,请参阅Windows系统日志.查阅 ...

  6. 微信小程序错误readFile:fail parameter error: parameter.filePath should be String instead of Undefined;

    我是在使用camera组件时遇到的该问题 原因是未保存文件路径(微信使用摄像头拍照后会把图片保存在一个临时的路径,所以你需要自己定义一个变量来存这个路径,以备下次使用该变量去访问文件) 所以加上你需要 ...

  7. Linux 之 搜索

    locate - 文件名搜索命令 用于查找文件 格式为:locate 文件名 该命令用于查找符合条件的文件,它会去保存文件与目录名称的数据库内,查找合乎范本样式条件的文件或目录. 因为该命令是直接在数 ...

  8. Zabbix监控平台-----深入理解zabbix

    一,Zabbix Web操作深入 (1)创建一个模版,所有的功能几乎都是在模版中定义的 点进新创建的模版查看,模版里几乎可以设定我们需要的所有功能 (2)在模版里创建应用集,应用集的作用就是将众多的监 ...

  9. 用js刷剑指offer(栈的压入、弹出序列)

    题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...

  10. Luogu P1294 高手去散步

    Luogu P1294 高手去散步 因为数据较小,所以用邻接矩阵存图即可. 将1号点到$t$号点分别设为起点,深搜遍历路线,开一个$vis$数组,记录每一个点是否被访问过.每次求出从当前起点出发的最大 ...