link

\(\text{Description:}\)

一个国家有 \(n\) 个城市,\(m\) 条有向道路组成。在这个国家一个星期有 \(d\) 天,每个城市有一个博物馆。

有个旅行团在城市 \(1\) 出发,当天是星期一。每天早上,如果这个城市的博物馆开了,那么可以去这个博物馆参观。每天晚上,旅行团可以选择沿一条出边前往下一个城市,或者结束旅行。一个城市可以经过多次。

请问旅行团最多能参观多少个博物馆。一个博物馆参观了多次,只计算一次。

\(1\le n, m\le 10^5,1\le d\le 50\)

\({\rm Solution:}\)

由于\({\rm d}\)只有\({\rm 50}\)天,所以考虑分层图,分成\({\rm 50}\)层,每个点只有在它开放的那个时间(那一层)有\({\rm 1}\)的权值,其余权值均为\({\rm 0}\),对于原图的一条边 \({\rm E(x, y)}\), 在分层图中 \({\rm E(x_i, y_{i+1}), (1\le i\le d-1)}\) 且 \({\rm E(x_d, y_1)}\)。

然后缩点成\({\rm DAG}\), \({\rm DP}\) 即可。

注意一个细节就是如果很多个点 \({\rm x_i}\) 在同一个强连通分量中,权值只加一次。

#include <vector>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <assert.h>
#include <algorithm> using namespace std; #define LL long long
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define GO debug("GO\n")
#define rep(i, a, b) for (register int (i) = (a); (i) <= (b); ++ (i)) const int INF = 0x3f3f3f3f;
const char Enter = '\n';
inline int rint() {
register int x = 0, f = 1; register char c;
while (!isdigit(c = getchar())) if (c == '-') f = -1;
while (x = (x << 1) + (x << 3) + (c ^ 48), isdigit(c = getchar()));
return x * f;
}
struct Stream {
Stream operator>> (int &x)
{ x = rint(); return *this; }
Stream operator<< (int x)
{ printf("%d", x); return *this; }
Stream operator<< (char ch)
{ putchar(ch); return *this; }
} xin, xout; template<typename T> inline void chkmin(T &a, T b) { a > b ? a = b : 0; }
template<typename T> inline void chkmax(T &a, T b) { a < b ? a = b : 0; } const int N = 1e5 + 10; struct Edge {
int v, nxt;
} E[N * 51];
int tot, head[N * 51];
vector<int> G[N * 51]; inline void add(int u, int v)
{ E[++tot] = (Edge){v, head[u]}; head[u] = tot; } int n, m, d, val[N * 50], col[N * 50], dfn[N * 50], low[N * 50], have[N * 50]; stack<int> stk;
void tarjan(int u) {
dfn[u] = low[u] = ++dfn[0];
stk.push(u);
for (register int i = head[u]; i; i = E[i].nxt) {
int v = E[i].v;
if (!dfn[v]) tarjan(v), chkmin(low[u], low[v]);
else if (!col[v]) chkmin(low[u], dfn[v]);
}
if (dfn[u] == low[u]) {
col[0]++;
int v;
do {
v = stk.top(); stk.pop();
col[v] = col[0];
} while (v != u);
}
} int dp[N * 50]; int DFS(int u) {
if (dp[u]) return dp[u];
for (int i = 0; i < G[u].size(); ++ i) {
int v = G[u][i];
chkmax(dp[u], DFS(v));
}
return dp[u] += val[u];
} int main() {
xin >> n >> m >> d;// fast_read
int u, v;
rep(i, 1, m) {
xin >> u >> v;
rep(j, 1, d - 1) add(u + (j - 1) * n, v + j * n);
add(u + (d - 1) * n, v);
}
rep(i, 1, d * n) if (!dfn[i]) tarjan(i); rep(i, 1, n * d) for (register int j = head[i]; j; j = E[j].nxt) if (col[E[j].v] != col[i])
G[col[i]].push_back(col[E[j].v]); rep(i, 1, n) {
static char str[N]; scanf("%s", str + 1);
rep(j, 1, d) {
if (str[j] == '1' and have[col[i + (j - 1) * n]] != i)
have[col[i + (j - 1) * n]] = i, val[col[i + (j - 1) * n]]++;
}
} xout << DFS(col[1]) << Enter; return 0;
}

[CF1137]Museums Tour的更多相关文章

  1. CF1137 C. Museums Tour

    CF1137 C. Museums Tour 一般来说的正常思路:看到有向图的第一思路都是缩点(但是要分析一波证明强联通分量中的个体可以拼凑成整体,一般都是边和点可以经过无数次然后贡献只算一次这种类型 ...

  2. CF 1138 E. Museums Tour

    E. Museums Tour 链接 分析: 按时间建出分层图,每个点形如(u,t),表示u在在t个时刻的点,tarjan缩点.每个强连通分量中的点都能经过,然后DAG上dp. 代码: #includ ...

  3. CF1137C Museums Tour(Tarjan,强连通分量)

    好题,神题. 题目链接:CF原网 洛谷 题目大意: 一个国家有 $n$ 个城市,$m$ 条有向道路组成.在这个国家一个星期有 $d$ 天,每个城市有一个博物馆. 有个旅行团在城市 $1$ 出发,当天是 ...

  4. 【Codeforces 1137C】Museums Tour

    Codeforces 1137 C 题意:给一个有向图,一周有\(d\)天,每一个点在每一周的某些时刻会开放,现在可以在这个图上从\(1\)号点开始随意地走,问最多能走到多少个开放的点.一个点如果重复 ...

  5. CF1137C Museums Tour

    思路 强连通分量的好题 对于每个博物馆,因为时间的限制条件,不好直接统计, 发现d很小,可以建出d层分层图,原图<u,v>的边变成<u,i>到<v,i+1>的边,& ...

  6. Codeforces 1137C Museums Tour (强连通分量, DP)

    题意和思路看这篇博客就行了:https://www.cnblogs.com/cjyyb/p/10507937.html 有个问题需要注意:对于每个scc,只需要考虑进入这个scc的时间即可,其实和从哪 ...

  7. 【CF1137C】 Museums Tour 拆点+缩点

    https://codeforc.es/contest/1137/problem/C # 题意 给你n个点,每个点有k天博物馆开放时间的安排表. 有m条单向道路,走过一条边需要一个晚上,经过后就是第二 ...

  8. CF1137C Museums Tour(tarjan+DP)

    由于d很小,所以可以把每个点拆成d个点,然后对于边(x,y),连边时连接((x,i),(y,i+1))及((x,d),(y,1)).然后可以对这样连的边跑一遍tarjan缩点.然后直接暴力DP即可.不 ...

  9. codeforces选做

    收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故 ...

随机推荐

  1. SSM项目引入文件失败

    <mvc:resources mapping="/styles/**" location="/css/"/> <mvc:resources m ...

  2. Ext JS 6和Sencha CMD 6 快速入门

    Ext JS 6和Sencha CMD 6的入门很简单.一个命令,即可生成一个功能完整的“通用”应用程序,可以运行在本地服务器上. 这个“通用”的应用程序包含一组核心的stores,模型(models ...

  3. chromium之MessageLoop浅析

    对chromium的MessageLoop非常感兴趣,接下来会详细分析Windows平台的具体实现. 代码版本:chromium-4.0.210.0_p26329 先看一下依赖的文件 message_ ...

  4. vdbench 数据校验测试方法

    [root@dntosu001 vdbench]# cat pbd.conf*SD: Storage Definition*WD: Workload Definition*RD: Run Defini ...

  5. 使用VMware安装CentOS7

    以前一直用的CentOS6,这次搭建一套CentOS7. 感觉和6还是有一些差异,在这边记录下. 一.选择典型(推荐): 二.选择安装程序光盘映像文件: 网上有几个版本,mini版,DVD版,不过mi ...

  6. crontab基础笔记 思维导图版

    直接上图吧----------------------------------------------------------------------------------------------- ...

  7. jqu

    1 /*2 * 说明:3 * 本源代码的中文注释乃Auscarlin呕心沥血所作.旨在促进jQuery的传播以及向广大jQuery爱好者提供一个进阶4 *的途径,以让各位更加深入地了解jQuery,学 ...

  8. php 计算两个日期相差天数

    <?php $startdate=strtotime("2013-3-09"); $enddate=strtotime("2013-4-05"); $da ...

  9. Delphi XE7调用Java Class,JAR

    Delphi XE5,XE6需要用户手工编译并将Classes.Dex加入到包中,不过Delphi XE7可以省掉这些工作了. 如何在XE7中调用Java,具体步骤如下: 1.将jar文件添加到XE7 ...

  10. Docker集群部署SpringCloud应用

    整体架构 docker环境准备 # linux下的安装,自行百度 # windows docker toolbox下载地址 https://download.docker.com/win/stable ...