1. 程式人生 > >洛谷——P2169 正則表達式

洛谷——P2169 正則表達式

整數 所有 表達 ont tdi pac 接下來 int 童鞋

P2169 正則表達式

題目背景

小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。

輸出格式:

輸出文件僅一行為最短傳輸時間。

輸入輸出樣例

輸入樣例#1: 復制
3 2
1 2 1
2 3 1
輸出樣例#1: 復制
2
輸入樣例#2: 復制
5 5
1 2 1
2 3 6
3 4 1
4 2 1
3 5 2
輸出樣例#2: 復制
3

說明

對於40%的數據,1<=n<=1000, 1<=m<=10000

對於70%的數據,1<=n<=5000, 1<=m<=100000

對於100%的數據,1<=n<=200000, 1<=m<=1000000

算是比較水了,只要你會tarjan縮點+spfa求最短路

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>

#define
N 101010 using namespace std; int tot,n,m,tpt,head[N],phead[N]; struct nodE{ int to,next,w; }e[N],p[N]; void add(int u,int v,int w){ e[++tot].to=v,e[tot].next=head[u],head[u]=tot,e[tot].w=w; } void Add(int u,int v,int w){ p[++tpt].to=v,p[tpt].next=phead[u],phead[u]=tpt,p[tpt].w=w; } int dfn[N],low[N],item,cnt,belong[N]; bool vis[N]; stack<int>S; void tarjan(int u){ dfn[u]=low[u]=++item; vis[u]=1; S.push(u); for(int i=head[u];i;i=e[i].next){ int v=e[i].to; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); }else if(vis[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ int v=u;++cnt; do{ v=S.top();S.pop(); vis[v]=0,belong[v]=cnt; }while(v!=u); } } queue<int>Q; int d[N]; void spfa(){ memset(vis,0,sizeof(vis)); memset(d,0x3f,sizeof(d)); Q.push(belong[1]);vis[belong[1]]=1,d[belong[1]]=0; while(!Q.empty()){ int u=Q.front();Q.pop();vis[u]=0; for(int i=phead[u];i;i=p[i].next){ int v=p[i].to; if(d[v]>d[u]+p[i].w){ d[v]=d[u]+p[i].w; if(!vis[v]){ Q.push(v); vis[v]=1; } } } } } int main() { scanf("%d%d",&n,&m); for(int u,v,w,i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); add(u,v,w); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++){ for(int j=head[i];j;j=e[j].next){ int v=e[j].to; if(belong[v]!=belong[i]){ Add(belong[i],belong[v],e[j].w); } } } spfa(); printf("%d",d[belong[n]]); return 0; }

洛谷——P2169 正則表達式