【洛谷 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求缩点,然后将每个缩点用边连起来,跑一边最短路即可。
小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 ]); }
相关文章推荐
- 洛谷 P2169 正则表达式
- 洛谷 P2169 正则表达式
- 洛谷 P2169 正则表达式
- Tarjan缩点+SPFA——正则表达式
- [linux学习笔记]第3天:变量分类,重定向,管道命令,程序执行流,文本处理类命令, 正则表达式,短路操作符
- 正则表达式--常用
- 常用正则表达式 整理篇
- 正则表达式特殊字符转义
- Java 正则表达式详解
- 正则表达式
- 让正则表达式更有趣一些!
- 用正则表达式验证邮箱和手机号
- Java 正则表达式
- python3爬虫之入门和正则表达式,获取IP地址, 隐马尔可夫模型及其在分词中的简单应用
- 正则表达式
- python最全的常用正则表达式大全——包括校验数字、字符、一些特殊的需求等等
- Python3正则表达式基础
- 正则表达式提取sql语句的@参数名,顺便修正subsonic的一个bug
- 正则表达式
- 使用正则表达式