[CF1137]Museums Tour
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的更多相关文章
- CF1137 C. Museums Tour
CF1137 C. Museums Tour 一般来说的正常思路:看到有向图的第一思路都是缩点(但是要分析一波证明强联通分量中的个体可以拼凑成整体,一般都是边和点可以经过无数次然后贡献只算一次这种类型 ...
- CF 1138 E. Museums Tour
E. Museums Tour 链接 分析: 按时间建出分层图,每个点形如(u,t),表示u在在t个时刻的点,tarjan缩点.每个强连通分量中的点都能经过,然后DAG上dp. 代码: #includ ...
- CF1137C Museums Tour(Tarjan,强连通分量)
好题,神题. 题目链接:CF原网 洛谷 题目大意: 一个国家有 $n$ 个城市,$m$ 条有向道路组成.在这个国家一个星期有 $d$ 天,每个城市有一个博物馆. 有个旅行团在城市 $1$ 出发,当天是 ...
- 【Codeforces 1137C】Museums Tour
Codeforces 1137 C 题意:给一个有向图,一周有\(d\)天,每一个点在每一周的某些时刻会开放,现在可以在这个图上从\(1\)号点开始随意地走,问最多能走到多少个开放的点.一个点如果重复 ...
- CF1137C Museums Tour
思路 强连通分量的好题 对于每个博物馆,因为时间的限制条件,不好直接统计, 发现d很小,可以建出d层分层图,原图<u,v>的边变成<u,i>到<v,i+1>的边,& ...
- Codeforces 1137C Museums Tour (强连通分量, DP)
题意和思路看这篇博客就行了:https://www.cnblogs.com/cjyyb/p/10507937.html 有个问题需要注意:对于每个scc,只需要考虑进入这个scc的时间即可,其实和从哪 ...
- 【CF1137C】 Museums Tour 拆点+缩点
https://codeforc.es/contest/1137/problem/C # 题意 给你n个点,每个点有k天博物馆开放时间的安排表. 有m条单向道路,走过一条边需要一个晚上,经过后就是第二 ...
- CF1137C Museums Tour(tarjan+DP)
由于d很小,所以可以把每个点拆成d个点,然后对于边(x,y),连边时连接((x,i),(y,i+1))及((x,d),(y,1)).然后可以对这样连的边跑一遍tarjan缩点.然后直接暴力DP即可.不 ...
- codeforces选做
收录了最近本人完成的一部分codeforces习题,不定期更新 codeforces 1132E Knapsack 注意到如果只使用某一种物品,那么这八种物品可以达到的最小相同重量为\(840\) 故 ...
随机推荐
- C编程规范, 演示样例代码。
/*************************************************************** *Copyright (c) 2014,TianYuan *All r ...
- 实现 在子界面的button按下,在主界面的label显示。
不知道理解的对不对,反正功能是实现了. 这是子界面,COM口配置界面的 .H文件的定义.下面的Private:定义了Ui:MainWindow *main_ui;的指针变量 要 注 ...
- ubuntu18.10手动安装mysql5.5
一.问题描述 本人使用的电脑安装的是ubuntu18.10系统,使用aptitude install mysql-server命令安装mysql时,总是无法正常安装,无法正常配置mysql-serve ...
- MySQL学习【第十一篇存储引擎之事务解释】
一.innodb的核心特点------事务 1.什么是事务 在一组数据操作执行步骤,这些步骤被视为一个单元,主要针对dml语句(update.delete.insert) 2.事务ACID特性 Ato ...
- jquery 60s倒计时
前端开发中经常用到的发送按钮倒计时,每次都是重写,挺麻烦的,记录一下,以后直接来复制代码 <!DOCTYPE html> <html> <head> <met ...
- 前端基础-HTTP协议
一. HTTP协议简介 二. HTTP协议之请求Request 三. HTTP协议之响应Response 四. HTTP协议完整工作流程 五. HTTP协议关键性总结 六.自定义套接字分析HTTP协议 ...
- PHP递归无限分类,数组和直接输出。
去年在一家公司做项目开发,用到商城三级分类,看了之前的程序员写的分类也是头大,三级分类,循环套循环三次( foreach(){ foreach(){ foreach(){ } } } ),然后写了一个 ...
- mapreduce使用 left outer join 的几种方式
需求 数据: [主表]:存放在log.txt中 -------------------------------------------------------- 手机号码 品牌类型 登录时间 在线时长 ...
- IAR新建MSP430工程
一.在IAR官网下载IAR for MSP430 软件 https://www.iar.com/iar-embedded-workbench/#!?architecture= 选择MSP430,然后 ...
- Java学习笔记三十:Java小项目之租车系统
Java小项目之租车系统 一:项目背景介绍: 根据所学知识,编写一个控制台版的“呱呱租车系统” 功能: 1.展示所有可租车辆: 2.选择车型.租车量: 3.展示租车清单,包含:总金额.总载货量以及其车 ...