正则表达式
题目背景
小Z童鞋一日意外的看到小X写了一个正则表达式的高级程序,这个正则表达式程序仅仅由字符“0”,“1”,“.”和“*”构成,但是他能够匹配出所有在OJ上都AC的程序的核心代码!小Z大为颇感好奇,于是他决定入侵小X的电脑上去获得这个正则表达式的高级程序。
题目描述
在 Internet 网络中的每台电脑并不是直接一对一连通的,而是某些电脑之间存在单向的网络连接,也就是说存在 $A$ 到 $B$ 的连接不一定存在 $B$ 到 $A$ 的连接,并且有些连接传输速度很快,有些则很慢,所以不同连接传输所花的时间是有大有小的。另外,如果存在 $A$ 到 $B$ 的连接的同时也存在 $B$ 到 $A$ 的连接的话,那么 $A$ 和 $B$ 实际上处于同一局域网内,可以通过本地传输,这样花费的传输时间为 $0$。
现在小 Z 告诉你整个网络的构成情况,他希望知道从他的电脑(编号为 $1$),到小 X 的电脑(编号为 $n$)所需要的最短传输时间。
输入格式
第一行两个整数 $n,m$,表示有 $n$ 台电脑,$m$ 个连接关系。
接下来 $m$ 行,每行三个整数 $u,v,w$,表示从电脑 $u$ 到电脑 $v$ 传输信息的时间为 $w$。
输出格式
输出文件仅一行为最短传输时间。
样例输入
5 5
1 2 1
2 3 6
3 4 1
4 2 1
3 5 2
样例输出
3
实现
简述一下题目,存在一有向有环图,在任意强连通块里面的路径权值均可看作0,求1号点到n号点最短路。
在tarjan缩点得到的有向无环图上跑一遍Dijkstra即可得到答案
#include<bits/stdc++.h>
using namespace std;
#define int long long
constexpr int inf32 = 1e9 + 7;
constexpr int inf64 = 1e9 + 7;
const int N=2e5;
struct tree{
int to;
int w;
};
vector<tree>e[N];
vector<tree>e_dist[N];
int cnt,idx,num;
int dfn[N],instk[N],low[N];
int belong[N];
stack<int> stk;
vector<int>scc[N];
int dout[N];
typedef pair<int,int> PII;
void tarjan(int u){
dfn[u]=low[u]=++idx;
stk.push(u);
instk[u]=1;
for(auto V:e[u]){
int v=V.to;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instk[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
cnt++;
int v;
do{
v=stk.top();
stk.pop();
instk[v]=0;
scc[cnt].push_back(v);
belong[v]=cnt;
}while(v!=u);
}
}
int dist[N];
void dijkstra(int u){
priority_queue<PII,vector<PII>,greater<PII>> q;
dist[u]=0;
q.push({0,u});
while(!q.empty()){
auto [distance,k]=q.top();
q.pop();
for(auto V:e_dist[k]){
int v=V.to;
int w=V.w;
if(dist[v]>distance+w){
dist[v]=distance+w;
q.push({dist[v],v});
}
}
}
}
void solve(){
int n,m;
cin>>n>>m;
memset(dist,127,sizeof(dist));
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
e[u].push_back({v,w});
}
for(int i=1;i<=n;i++){
if(!dfn[i]) tarjan(i);
}
for(int i=1;i<=cnt;i++){
for(auto u:scc[i]){
for(auto v:e[u]){
e_dist[i].push_back({belong[v.to],v.w});
}
}
}
dijkstra(belong[1]);
cout<<dist[belong[n]]<<endl;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
solve();
}
}