【洛谷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

分析

代码

#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]]);
}
    

 

posted @ 2017-09-14 22:27  沐灵_hh  阅读(203)  评论(0编辑  收藏  举报