题目背景
小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。
输出格式:
输出文件仅一行为最短传输时间。
输入输出样例
说明
对于40%的数据,1<=n<=1000, 1<=m<=10000
对于70%的数据,1<=n<=5000, 1<=m<=100000
对于100%的数据,1<=n<=200000, 1<=m<=1000000
#include<bits/stdc++.h> #define REP(i, a, b) for(int i = (a); i <= (b); ++ i) #define REP(j, a, b) for(int j = (a); j <= (b); ++ j) #define PER(i, a, b) for(int i = (a); i >= (b); -- i) using namespace std; const int maxn=2e6+5; template <class T> inline void rd(T &ret){ char c; ret = 0; while ((c = getchar()) < '0' || c > '9'); while (c >= '0' && c <= '9'){ ret = ret * 10 + (c - '0'), c = getchar(); } } struct node{ int u,v,t,nx; }p[3000010]; int n,m,vis[maxn],head[maxn],tot,dis[maxn],dfn[maxn],low[maxn],cnt,gt[maxn]; void addedge(int u,int v,int w){ p[++tot].v=v,p[tot].nx=head[u],head[u]=tot,p[tot].t=w; } stack<int>sk; void tarjan(int cur){ dfn[cur]=low[cur]=++tot; sk.push(cur); vis[cur]=1; for(int i=head[cur];i;i=p[i].nx){ int to=p[i].v; if(!dfn[to]){ tarjan(to); low[cur]=min(low[cur],low[to]); } else if(vis[to])low[cur]=min(low[cur],dfn[to]); } if(dfn[cur]==low[cur]){ int now; cnt++; do{ now=sk.top(); sk.pop(); vis[now]=0; gt[now]=cnt; }while(now!=cur); } } void spfa(){ REP(i,1,n)vis[i]=0; memset(dis,0x7f,sizeof(dis)); memset(vis,0,sizeof(vis)); queue<int>q; q.push(1); vis[1]=1,dis[1]=0; while(!q.empty()){ int cur=q.front(); q.pop(); vis[cur]=0; for(int i=head[cur];i;i=p[i].nx){ int to=p[i].v; if(gt[to]==gt[cur])p[i].t=0; if(dis[to]>dis[cur]+p[i].t){ dis[to]=dis[cur]+p[i].t; if(!vis[to]){ q.push(to); vis[to]=1; } } } } } int main() { rd(n),rd(m); REP(i,1,n)dis[i]=1e9; REP(i,1,m){ int u,v,w; scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); } tot=0; REP(i,1,n)if(!dfn[i])tarjan(i); spfa(); cout<<dis[n]<<endl; return 0; }