您的位置:首页 > 其它

【洛谷 P2169】正则表达式 tarjan+最短路

2016-12-10 11:25 447 查看
题目背景

小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求缩点,然后将每个缩点用边连起来,跑一边最短路即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 200006
using namespace std;
struct node
{
int from,to,next,dis;
}e[1000006];
int low
,dfn
,insex,stack
,tot;
bool instack
;
int e_num,head
;
bool flag
;
int color
;
int n,t,ans,m;
int maxx=1e9,minn=0;
int a
,b
,ru
,w
;
int c
;
int get()
{
int x=0,p=1;char c;
c=getchar();
while (c<'0'||c>'9') {if (c=='-') p=-1;c=getchar();}
while (c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*p;
}
void add(int from,int to)
{
++e_num;
e[e_num].from=from;
e[e_num].to=to;
e[e_num].next=head[from];
head[from]=e_num;
}
void add_tarjan(int from,int to,int dis)
{
++e_num;
e[e_num].from=from;
e[e_num].to=to;
e[e_num].dis=dis;
e[e_num].next=head[from];
head[from]=e_num;
}
void tarjan(int u)
{
int i;
low[u]=dfn[u]=++insex;
instack[u]=true;
stack[++tot]=u;
for (i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if (!dfn[v])
{
tarjan(v);
low[u]=min(low[v],low[u]);
}
else if (instack[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if (low[u]==dfn[u])
{
int tmp=0;
++t;
while (tmp!=u)
{
tmp=stack[tot--];
instack[tmp]=false;
color[tmp]=t;
}
}
}
int find(int x,int y)
{
int time=1e9,i;
for (i=1;i<=m;i++)
if (color[a[i]]==x&&color[b[i]]==y)
{
time=min(time,w[i]);
}
return time;
}
void slove()
{
int i;
memset(dfn,0,sizeof(dfn));
for (i=1;i<=n;i++)
if (!dfn[i])
tarjan(i);
}
void dijkstra()
{
int i,j,k;
memset(flag,false,sizeof(flag));
for (i=1;i<=t;i++)
c[i]=maxx;
c[color[1]]=0;
for (i=1;i<=t;i++)
{
k=0;
minn=maxx;
for (j=1;j<=t;j++)
if (c[j]<minn&&!flag[j])
{
minn=c[j];
k=j;
}
if (k==0) break;
flag[k]=true;
for (j=head[k];j;j=e[j].next)
if (c[e[j].to]>c[k]+e[j].dis)
{
c[e[j].to]=c[k]+e[j].dis;
}
}
}
int main()
{
int x,i,y,z,time;
n=get();m=get();
for (i=1;i<=m;i++)
{
x=get();y=get();z=get();
add(x,y);
a[i]=x;b[i]=y;w[i]=z;
}
slove();
//  for (i=1;i<=n;i++)
//      printf("%d ",color[i]);
if (color[1]==color
) {printf("0");return 0;}
e_num=0;
memset(e,0,sizeof(e));
memset(head,0,sizeof(head));
for (i=1;i<=m;i++)
if (color[a[i]]!=color[b[i]])
{
time=find(color[a[i]],color[b[i]]);
add_tarjan(color[a[i]],color[b[i]],time);
}
dijkstra();
printf("%d",c[color
]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: