题目链接

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

Codeforces 576D Flights for Regular Customers (图论、矩阵乘法、Bitset)的更多相关文章

  1. Codeforces 576D Flights for Regular Customers(矩阵加速DP)

    题目链接  Flights for Regular Customers 首先按照$d$的大小升序排序 然后分成$m$个时刻,每条路径一次处理过来. $can[i][j]$表示当前时刻$i$能否走到$j ...

  2. Codeforces 576D. Flights for Regular Customers(倍增floyd+bitset)

    这破题调了我一天...错了一大堆细节T T 首先显然可以将边权先排序,然后逐个加进图中. 加进图后,倍增跑跑看能不能到达n,不能的话加新的边继续跑. 倍增的时候要预处理出h[i]表示转移矩阵的2^0~ ...

  3. Codeforces 576D - Flights for Regular Customers(bitset 优化广义矩阵乘法)

    题面传送门 题意: 有一张 \(n\) 个点 \(m\) 条边的有向图,你初始在 \(1\) 号点,边上有边权 \(c_i\) 表示只有当你经过至少 \(c_i\) 条边的时候你才能经过第 \(i\) ...

  4. Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP

    题意: 给一个$n$点$m$边的连通图 每个边有一个权值$d$ 当且仅当当前走过的步数$\ge d$时 才可以走这条边 问从节点$1$到节点$n$的最短路 好神的一道题 直接写做法喽 首先我们对边按$ ...

  5. (中等) CF 576D Flights for Regular Customers (#319 Div1 D题),矩阵快速幂。

    In the country there are exactly n cities numbered with positive integers from 1 to n. In each city ...

  6. 576D Flights for Regular Customers

    分析 https://www.cnblogs.com/onioncyc/p/8037056.html 写的好像有点问题 但是大致就是这个意思 代码很好理解 代码 #include<bits/st ...

  7. CF576D Flights for Regular Customers 矩阵乘法 + Bitset优化

    %%%cxhscst2's blog Codeforces 576D Flights for Regular Customers(矩阵加速DP) 代码非常优美 + 简洁,学习到了 Code: #inc ...

  8. 【CodeForces】576 D. Flights for Regular Customers

    [题目]D. Flights for Regular Customers [题意]给定n个点m条边的有向图,每条边有di表示在经过该边前必须先经过di条边,边可重复经过,求1到n的最小经过边数.n,m ...

  9. 「CF576D」 Flights for Regular Customers

    「CF576D」 Flights for Regular Customers 对不起我又想网络流去了 你看这长得多像啊,走过至少多少条边就是流量下界,然后没上界 但是这个题求的最少走多少条边啊...完 ...

随机推荐

  1. Spring实战(四)Spring高级装配中的bean profile

    profile的原意为轮廓.剖面等,软件开发中可以译为“配置”. 在3.1版本中,Spring引入了bean profile的功能.要使用profile,首先要将所有不同的bean定义整理到一个或多个 ...

  2. Apache开启.htaccess 支持

    (1) <Directory "${SRVROOT}/htdocs"> # # Possible values for the Options directive ar ...

  3. linux--查看磁盘空间大小使用情况

    1. linux查看磁盘空间大小命令 df -h Df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息, 命令格式: df -hl  显示格式为:  文件系统 容量  ...

  4. 13.MySQL锁机制

    锁的分类 从对数据的类型 (读\写)分: 1.读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响 2.写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁 从对数据操作的粒度 ...

  5. 工作总结 页面 ActionResult / JsonResult 将对象以 Json() 返回

    其实都不用在页面上序列化   打印 都不需要在页面上 像这样  var ajaxResult = eval("(" + data + ")");  序列化为对象 ...

  6. 第四章、Django之模型层---创建模型

    目录 第四章.Django之模型层---创建模型 一.写models.py 第四章.Django之模型层---创建模型 一.写models.py from django.db import model ...

  7. shiro系列二、身份验证和授权

    一.身份验证 先来看看身份验证的流程 流程如下: 1.首先调用Subject.login(token)进行登录,其会自动委托给Security Manager,调用之前必须通过SecurityUtil ...

  8. Linux的bg和fg命令

    我们都知道,在 Windows 上面,我们要么让一个程序作为服务在后台一直运行,要么停止这个服务.而不能让程序在前台后台之间切换.而 Linux 提供了 fg 和 bg 命令,让我们轻松调度正在运行的 ...

  9. python django中的orm外键级联删除

    今天添加了一个路由表,路由表做外键,然后添加了几个组,路由表为组的外键,当我使用删除功能对路由表进行删除时,竞然将我的组也相当的删除了:尽管这是测试,但放到生产环境中还是会发生意外的:这个问题要解决: ...

  10. 实验楼Python项目

    整理几个实验楼小项目,有免费的也有会员的,会员的可以参考他们的实验报告. 直接去实验楼这个网站,粘贴上就能搜到. 免费专区: Kmeans聚类算法评估足球比赛 Python实现3D建模工具 K-近邻算 ...