题目背景
小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
分析
代码
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; const int maxn=200000+5; const int maxm=1000000+5; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();} return x*f; } int n,m,num,id,cnt,top; int head[maxn],dis[maxn],u[maxn],v[maxn],w[maxn]; int low[maxn],dfn[maxn],sta[maxn],belong[maxn]; bool ins[maxn],inq[maxn]; struct node { int next,to,dist; }e[maxm]; queue<int>q; inline void add(int from,int to,int dist) { e[++num].next=head[from]; e[num].to=to; e[num].dist=dist; head[from]=num; } void tarjan(int x) { dfn[x]=low[x]=++id; ins[x]=1;sta[++top]=x; int to; for(int i=head[x];i;i=e[i].next) { to=e[i].to; if(!dfn[to]) { tarjan(to); low[x]=min(low[x],low[to]); }else if(ins[to]) low[x]=min(low[x],dfn[to]); } if(dfn[x]==low[x]) { cnt++; do { to=sta[top--]; ins[to]=0; belong[to]=cnt; }while(to!=x); } } void spfa(int s) { memset(dis,0x3f,sizeof(dis)); q.push(s); inq[s]=1; dis[s]=0; while(!q.empty()) { int u=q.front();q.pop();inq[u]=0; for(int i=head[u];i;i=e[i].next) { int to=e[i].to; if(dis[to]>dis[u]+e[i].dist) { dis[to]=dis[u]+e[i].dist; if(!inq[to]) { q.push(to); inq[to]=1; } } } } } int main() { n=read();m=read(); for(int i=1;i<=m;i++) { u[i]=read();v[i]=read();w[i]=read(); add(u[i],v[i],w[i]); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); num=0; memset(head,0,sizeof(head)); for(int i=1;i<=m;i++) { if(belong[u[i]]!=belong[v[i]]) add(belong[u[i]],belong[v[i]],w[i]); } spfa(belong[1]); printf("%d\n",dis[belong[n]]); }
时间: 2024-10-12 18:54:41