首页 > 技术文章 > 洛谷——P2169 正则表达式

song- 2018-09-01 19:24 原文

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;
} 

 

推荐阅读