[Luogu 2169] 正则表达式

<题目链接>


感谢 0xis 推题。

记忆中很久没有过一遍写过一题了…

别被题目名称蒙骗!这不是正则表达式题目!和字符(串)处理一点关系都没有!这是个图论题啊喂!

题都没急,Capella 你急啥?

由题意得,能够本地传输的机子们处于同一强连通分量,于是 Tarjan 一遍,缩点。缩的过程中,对于两个 SCC 之间的边,选短的加。

我这里用一个 map,记录边(pair<int, int>)到边权(int)的映射,然后用 map 判断是否加边就好了。

最短路,跑一个 Dijkstra 即可(珍爱生命,远离某死亡算法不解释)。

输出 1 所在的 SCC 到 n 所在的 SCC 的路径。

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <stack> #define nullptr NULL const int MAXN = 200010; int n, m; namespace SCC
{
bool exist[MAXN], vis[MAXN];
int num, sum, DFN[MAXN], low[MAXN], SCC[MAXN], dist[MAXN];
std :: stack<int> S;
struct Node
{
int index, dist;
Node(int index, int dist): index(index), dist(dist) {}
bool operator <(const Node& rhs) const
{
return dist > rhs.dist;
}
};
struct Graph
{
struct Edge
{
int to, w;
Edge *next;
Edge(int to, int w, Edge* next): to(to), w(w), next(next) {}
~Edge(void)
{
if(next != nullptr)
delete next;
}
}*head[MAXN];
Graph(int n)
{
std :: fill(head + 1, head + n + 1, (Edge*)nullptr);
}
~Graph(void)
{
for(int i = 1; i <= n; ++i)
delete head[i];
}
void AddEdge(int u, int v, int w)
{
head[u] = new Edge(v, w, head[u]);
}
}*G, *Gnew;
void Tarjan(int u)
{
S.push(u);
exist[u] = true;
DFN[u] = low[u] = ++num;
int v;
for(Graph :: Edge *i = G -> head[u]; i != nullptr; i = i -> next)
if(!DFN[v = i -> to])
{
Tarjan(v);
low[u] = std :: min(low[u], low[v]);
}
else if(exist[v])
low[u] = std :: min(low[u], DFN[v]);
if(DFN[u] == low[u])
{
++sum;
do
{
exist[v = S.top()] = false;
S.pop();
SCC[v] = sum;
}
while(u ^ v);
}
}
void Shrink(void)
{
std :: map<std :: pair<int, int>, int> QAQ;
std :: pair<int, int> t;
Gnew = new Graph(sum);
for(int u = 1, v; u <= n; ++u)
for(Graph :: Edge *i = G -> head[u]; i != nullptr; i = i -> next)
if(!QAQ.count(t = std :: make_pair(SCC[u], SCC[v = i -> to])) || i -> w < QAQ[t])
{
Gnew -> AddEdge(SCC[u], SCC[v], i -> w);
QAQ[t] = i -> w;
}
}
void Dijkstra(int S)
{
std :: priority_queue<Node> Q;
memset(dist, 0x3f, sizeof dist);
Q.push(Node(S, dist[S] = 0));
while(!Q.empty())
{
int u = Q.top().index, v;
Q.pop();
if(!vis[u])
{
vis[u] = true;
for(Graph :: Edge *i = Gnew -> head[u]; i != nullptr; i = i -> next)
if(dist[v = i -> to] > dist[u] + i -> w)
Q.push(Node(v, dist[v] = dist[u] + i -> w));
}
}
}
void Solve(void)
{
for(int i = 1; i <= n; ++i)
if(!DFN[i])
Tarjan(i);
Shrink();
Dijkstra(SCC[1]);
printf("%d\n", dist[SCC[n]]);
}
} int main(void)
{
scanf("%d %d", &n, &m);
SCC :: G = new SCC :: Graph(n);
for(int i = 1, u, v, w; i <= m; ++i)
{
scanf("%d %d %d", &u, &v, &w);
SCC :: G -> AddEdge(u, v, w);
}
SCC :: Solve();
return 0;
}

谢谢阅读。

[Luogu 2169] 正则表达式的更多相关文章

  1. 【luogu P2169 正则表达式】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2169 tarjan缩点 + SPFA 缩完点之后加边注意别写错. 也可以不用建两个图,可以在一张图上判断是否 ...

  2. JS正则表达式常用总结

    正则表达式的创建 JS正则表达式的创建有两种方式: new RegExp() 和 直接字面量. //使用RegExp对象创建 var regObj = new RegExp("(^\\s+) ...

  3. Python高手之路【五】python基础之正则表达式

    下图列出了Python支持的正则表达式元字符和语法: 字符点:匹配任意一个字符 import re st = 'python' result = re.findall('p.t',st) print( ...

  4. C# 正则表达式大全

    文章导读 正则表达式的本质是使用一系列特殊字符模式,来表示某一类字符串.正则表达式无疑是处理文本最有力的工具,而.NET提供的Regex类实现了验证正则表达式的方法.Regex 类表示不可变(只读)的 ...

  5. C#基础篇 - 正则表达式入门

    1.基本概念 正则表达式(Regular Expression)就是用事先定义好的一些特定字符(元字符)或普通字符.及这些字符的组合,组成一个“规则字符串”,这个“规则字符串”用来判断我们给定的字符串 ...

  6. JavaScript正则表达式,你真的知道?

    一.前言 粗浅的编写正则表达式,是造成性能瓶颈的主要原因.如下: var reg1 = /(A+A+)+B/; var reg2 = /AA+B/; 上述两个正则表达式,匹配效果是一样的,但是,效率就 ...

  7. Python 正则表达式入门(中级篇)

    Python 正则表达式入门(中级篇) 初级篇链接:http://www.cnblogs.com/chuxiuhong/p/5885073.html 上一篇我们说在这一篇里,我们会介绍子表达式,向前向 ...

  8. 【JS基础】正则表达式

    正则表达式的() [] {}有不同的意思. () 是为了提取匹配的字符串.表达式中有几个()就有几个相应的匹配字符串. (\s*)表示连续空格的字符串. []是定义匹配的字符范围.比如 [a-zA-Z ...

  9. JavaScript 正则表达式语法

    定义 JavaScript定义正则表达式有两种方法. 1.RegExp构造函数 var pattern = new RegExp("[bc]at","i"); ...

随机推荐

  1. Redis4.0 主从复制(PSYN2.0)

    Redis4.0版本相比原来3.x版本,增加了很多新特性,如模块化.PSYN2.0.非阻塞DEL和FLUSHALL/FLUSHDB.RDB-AOF混合持久化等功能.尤其是模块化功能,作者从七年前的re ...

  2. sql update set from 的用法 (转)

    关键字: update set from 下面是这样一个例子: 两个表a.b,想使b中的memo字段值等于a表中对应id的name值     表a:id, name               1   ...

  3. 弱智python小游戏猜数字

    from random import randintnum = randint(0,100)print("Guess what I think:?")bingo = Falsewh ...

  4. linux使用密文生成os账户

    1.生成账户 [hufangrui@xxx ~]$ openssl passwd -1Password: Verifying - Password: $1$szzkROBZ$GYxffRLp8K5vW ...

  5. mysql索引利弊分析

    转载自:http://blog.csdn.net/linminqin/article/details/44342205  索引的利弊与如何判定,是否需要索引 相信读者都知道索引能够极大地提高数据检索的 ...

  6. logback错误日志发送邮件

    logback 一.介绍 logback是由log4j的作者开发的一个开源日志组件,用以替代log4j. logback由3个部分组成: ♦ logback-core (基础模块) ♦ logback ...

  7. Eclipse HTML Editor

    需插件: 1.GEF 3.1 安装程序下载 下载地址: http://download.eclipse.org/tools/gef/downloads/drops/R-3.1-200507071758 ...

  8. 手写简单的promise

    function Promise(fn) { var that = this; this.status = "pedding"; this.value = undefined; / ...

  9. poj 2185

    http://poj.org/problem?id=2185 题意:求最小的模式块,使其无限扩展后包含给你的矩阵块(看别人题解才懂的题意): 分析:假设存在一个模式块可以满足上述条件,那么必然存在一个 ...

  10. MT【132】倒序相加因式分解

    设数列\(\{a_n\}\)的前\(n\)项和\(S_n\)满足\(S_{n+1}=a_2S_n+a_1,\)其中\(a_2\ne 0\)且\(a_2>-1\) 求证:\(S_n\le \dfr ...