[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. angularJS1笔记-(19)-angular异步加载包的方式

    我们平时写的导入包的方式都是同步方式,有时候会显得过于卡顿,这样我们就可以使用异步加载的方式. script.js方式: 执行结果为: 异步加载还可以加载多个即为script([,,,],functi ...

  2. MongoDB中的数据导出为excel CSV 文件

    1.打开命令行,进入我们所安装的mongodb路径下的bin文件夹 2.我们采用bin文件夹下的mongoexport方法进行导出, mongoexport -d myDB -c user -f _i ...

  3. FineReport基本使用

    FineReport官方开发文档链接:http://help.finereport.com 1.FineReport是帆软软件有限公司自主研发的一款企业级web报表软件产品.FineReport报表软 ...

  4. 014 C语言文法定义与C程序的推导过程

  5. js ajax 经典案例

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. SqlServer日期时间函数

    -- 判断是否当天,createdate为日期字段 -- ╔════════════════════╗ -- ============================================= ...

  7. C# 实例化类的执行顺序

    先进行细分: 类的成员分为:字段.属性.方法.构造方法 成员的修饰符:静态成员.实例成员 层次结构:父类.子类 先不考虑继承关系,执行顺序为: 静态字段 静态构造方法 实例字段 实例构造方法 属性和方 ...

  8. selenium实战之斗鱼弹幕

    python3.6.selenium.chromedriver 先上代码 from selenium import webdriver from time import sleep driver=we ...

  9. AND Graph CodeForces - 987F(思维二进制dfs)

    题意:给出n(0≤n≤22)和m,和m个数ai,1 ≤ m ≤ 2n ,0≤ai<2n ,把ai & aj == 0 的连边,求最后有几个连通块 解析:一个一个去找肯定爆,那么就要转换一 ...

  10. 【模考】2018.04.08 Travel

    Description 有N个人出去旅行,第i个人去A国有Ai种游玩方式,去B国有Bi种游玩方式,问至少有C个人去A国的情况下,所有人的游玩方式有多少种不同的可能. 两种所有人的游玩方式不同当且仅当存 ...