题目链接

http://codeforces.com/contest/576/problem/D

题解

把边按\(t_i\)从小到大排序后枚举\(i\), 求出按前\((i-1)\)条边走\(t_i\)步能到达的点的集合,以它们为起点求\(n\)号点的最短路。

前者等于前\((i-2)\)条边走\(t_{i-1}\)步能到达的点集乘上前\((i-1)\)条边邻接矩阵的\((t_i-t_{i-1})\)次幂。

因为只关心是否存在,故可以使用bitset优化。

时间复杂度\(O(mn^3+\frac{n^3\log T}{\omega})\).

代码

#include<bits/stdc++.h>
using namespace std; inline int read()
{
int x = 0,f = 1; char ch = getchar();
for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
for(;!isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
return x*f;
} const int N = 150;
const int INF = 2e9;
struct AEdge
{
int u,v,t;
bool operator <(const AEdge &arg) const {return t<arg.t;}
} ae[N+3];
struct Edge
{
int v,nxt;
} e[(N<<1)+3];
int a[N+3];
int fe[N+3];
int que[N+3];
int dep[N+3];
bool vis[N+3];
int n,m,en; void addedge(int u,int v)
{
en++; e[en].v = v;
e[en].nxt = fe[u]; fe[u] = en;
} struct Matrix
{
bitset<N+3> a[N+3];
Matrix() {for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) a[i][j] = 0;}
Matrix operator *(const Matrix &arg) const
{
Matrix ret;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(a[i][j]) {ret.a[i]|=arg.a[j];}
}
}
return ret;
}
};
Matrix I,O,g,b; void clearedge()
{
for(int i=1; i<=n; i++) fe[i] = 0;
for(int i=1; i<=en; i++) e[i].v = e[i].nxt = 0;
en = 0;
} Matrix mquickpow(Matrix x,int y)
{
Matrix cur = x,ret = I;
for(int i=0; y; i++)
{
if(y&(1<<i)) {y-=(1<<i); ret = ret*cur;}
cur = cur*cur;
}
return ret;
} void bfs()
{
for(int i=1; i<=n; i++) vis[i] = false;
int hd = 1,tl = 0;
for(int i=1; i<=n; i++) {if(g.a[1][i]) {tl++; que[tl] = i; vis[i] = true; dep[i] = 0;}}
while(hd<=tl)
{
int u = que[hd]; hd++;
for(int i=fe[u]; i; i=e[i].nxt)
{
int v = e[i].v;
if(!vis[v]) {vis[v] = true; tl++; que[tl] = v; dep[v] = dep[u]+1;}
}
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) I.a[i].set(i);
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&ae[i].u,&ae[i].v,&ae[i].t);
}
sort(ae+1,ae+m+1);
g = I;
int ans = INF;
for(int i=1; i<=m; i++)
{
for(int j=1; j<=i; j++) {addedge(ae[j].u,ae[j].v);}
g = g*mquickpow(b,ae[i].t-ae[i-1].t);
bfs();
if(vis[n]) {ans = min(ans,ae[i].t+dep[n]);}
clearedge();
b.a[ae[i].u].set(ae[i].v);
}
if(ans==INF) puts("Impossible");
else printf("%d\n",ans);
return 0;
}

最新文章

  1. Linux中可用于管道操作的命令总结
  2. js中设置元素class的三种方法小结
  3. 【MongoDB】2.可视化工具的安装和使用
  4. floyd算法 poj2253
  5. php Output Control 函数 ob_系列函数详解
  6. mac上安装homebrew
  7. bzoj3698
  8. (转载)最黑的黑客米特尼克:多次耍FBI 终被高手擒
  9. poj 1383 Labyrinth【迷宫bfs+树的直径】
  10. 简单hdfs相关操作命令
  11. Android之获取屏幕的尺寸像素及获取状态栏标题栏高度
  12. 对于SQL注入的理解
  13. Android UI(四)云通讯录项目之云端更新进度条实现
  14. Gson将字符串转map时,int默认为double类型
  15. css布局 - 两栏自适应布局的几种实现方法汇总
  16. docker下debian镜像开启ssh, 允许root用密码登录
  17. (O)js核心:this
  18. MongoDB(课时19 数据删除)
  19. MySQL语句应该注意的问题
  20. Alpha冲刺——第十天

热门文章

  1. Spring mvc 参数半丁
  2. springboot内置tomcat配置虚拟路径
  3. maven 私服 nexus 安装
  4. 基于Hadoop生态SparkStreaming的大数据实时流处理平台的搭建
  5. JavaScript Basics_Fundamentals Part 2_A simple calendar
  6. struts访问jsp api内置对象的集中方式
  7. ssh-copy-id三步实现SSH无密码登录和ssh常用命令
  8. 关于select的困惑
  9. Django ORM常用的字段和参数
  10. (十二)A64