码迷,mamicode.com
首页 > 其他好文 > 详细

P2169 正则表达式

时间:2018-02-09 22:28:19      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:main   bad   pac   span   决定   就是   turn   post   print   

题目背景

小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

 

很显然,对于一个强连通分量,里面所有的通讯为0,所以可以看成一个点,因此想到tarjan缩点。

话不多说,之后对于进行spfa,注意当某边起点终点在同一个强连通分量时,修改边权为0。

还是很不错的一题。

AC代码如下:

#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
const int N=200000+5;
const int M=1000000+5;
const int INF=1<<28;
stack<int>s;
struct p{
    int to,w,nxt;
}e[M];
int fir[N],dfn[N],low[N],col[N],num,t,tot,x,y,z,n,m,dis[N];
bool in[N],inq[N];
void add(int from,int to,int ww)
{
    if(from==to) return;
    tot++;
    e[tot].to=to;
    e[tot].nxt=fir[from];
    e[tot].w=ww;
    fir[from]=tot;
    return;
}
void dfs(int x)
{
    in[x]=1;
    s.push(x);
    dfn[x]=low[x]=++t;
    for(int i=fir[x];i;i=e[i].nxt)
    if(!dfn[e[i].to]) dfs(e[i].to),low[x]=min(low[x],low[e[i].to]);
    else if(in[e[i].to]) low[x]=min(low[x],dfn[e[i].to]);

    if(dfn[x]==low[x])
    {
        num++;
        col[x]=num;
        in[x]=0;
        while(s.top()!=x) col[s.top()]=num,in[s.top()]=0,s.pop();
        s.pop();
    }
    return;
}
void solve()
{
    queue<int>q;
    q.push(1);
    inq[1]=1;
    dis[1]=0;
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        inq[now]=0;
        for(int i=fir[now];i;i=e[i].nxt)
        {
            
            if(col[e[i].to]==col[now]) e[i].w=0;
            if(dis[e[i].to]>dis[now]+e[i].w)
            {
                dis[e[i].to]=dis[now]+e[i].w;
                if(!inq[e[i].to]) inq[e[i].to]=1,q.push(e[i].to);
                
            }
        }
    }
    return;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    scanf("%d%d%d",&x,&y,&z),add(x,y,z);
    for(int i=1;i<=n;i++)
    {
        dis[i]=INF;
    if(!dfn[i]) dfs(i);
    }
    solve();
    printf("%d",dis[n]);
    return 0;
 } 

 

P2169 正则表达式

标签:main   bad   pac   span   决定   就是   turn   post   print   

原文地址:https://www.cnblogs.com/Alex-leaves/p/8436666.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!