【CF1137C】 Museums Tour 拆点+缩点
https://codeforc.es/contest/1137/problem/C
# 题意
给你n个点,每个点有k天博物馆开放时间的安排表。
有m条单向道路,走过一条边需要一个晚上,经过后就是第二天的意思。
问在无穷大的时间里,可以参观多少不同的博物馆。
# 思路
我们把每个点都拆出k个点,有单向边相连就从(u,i) -> (v, (i+1)%k)。
缩点跑出DAG,然后DP出最多的博物馆参观数。
这里就要考虑直接DP是否能行。假设有一条(u,i) -> (u, j)的边,由于没有自环且是单向边,所以一定可以通过循环,可以从(u,j)再走到(u,i),所以这两个点会缩在一起。
由于这种做法缩点时递归很深,我是通过inline优化的,开O(3)好像也可以。
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); }
template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
}
const int inf = 0x3f3f3f3f;
const int mod = 1e9+;
/**********showtime************/
const int maxn = ;
// vector<int>mp[maxn];
int n,m,k;
int getid(int x, int i) {
return (x - ) * k + i + ;
}
struct E{
int u,v;
int nxt;
}edge[maxn];
int gtot = , head[maxn];
void addedge(int u, int v) {
edge[gtot].u = u;
edge[gtot].v = v;
edge[gtot].nxt = head[u];
head[u] = gtot++;
}
set <int> dpmp[maxn];
char str[];
int dp[maxn],a[maxn];
int belong[maxn], dfn[maxn] , low[maxn];
bool vis[maxn];
bool flag[maxn];
// int used[maxn];
int tim, scc_cnt;
//stack<int>st;
queue<int>que;
int st[];
int top = ;
inline void dfs(int u) {
dfn[u] = low[u] = ++tim;
// st.push(u);
st[++top] = u;
for(int i=head[u]; ~i; i=edge[i].nxt){
int v = edge[i].v;
if(!dfn[v]) dfs(v);
if(!belong[v]) low[u] = min(low[u], low[v]);
}
if(dfn[u] == low[u]) {
scc_cnt++;
int now;
while(true) {
now = st[top]; top--;
belong[now] = scc_cnt;
if(flag[now]) {
int id = (now - ) / k + ;
if(vis[id] == ) {
que.push(id);
vis[id] = ;
a[scc_cnt]++;
}
}
if(now == u) break;
}
while(!que.empty()) {
int u = que.front(); que.pop();
vis[u] = ;
}
}
}
int ans = ; void cal(int s) {
queue<int>que;
dp[s] = a[s];
que.push(s);
ans = max(ans, a[s]);
while(!que.empty()) {
int u = que.front(); que.pop();
vis[u] = ;
for(int v : dpmp[u]) {
dp[v] = max(dp[v], dp[u] + a[v]);
ans = max(ans, dp[v]);
if(vis[v] == ) {
vis[v] = ;
que.push(v);
}
}
}
}
int main(){
memset(head, -, sizeof(head));
R(n, m, k);
for(int i=; i<=m; i++) {
int u,v;
scanf("%d%d", &u, &v);
for(int j=; j<k; j++) {
addedge(getid(u, j), getid(v, (j+)%k));
}
}
for(int i=; i<=n; i++) {
scanf("%s", str);
for(int j=; j<k; j++) {
flag[getid(i, j)] = (str[j] == '');
}
}
for(int i=; i<=n; i++){
for(int j=; j<k; j++)
if(!dfn[getid(i, j)]) dfs(getid(i, j));
}
for(int i=; i<gtot; i++){
int u = edge[i].u, v = edge[i].v;
if(belong[u] == belong[v]) continue;
dpmp[belong[u]].insert(belong[v]);
}
cal(belong[getid(, )]);
printf("%d\n", ans);
return ;
}
【CF1137C】 Museums Tour 拆点+缩点的更多相关文章
- CF1137C Museums Tour(Tarjan,强连通分量)
好题,神题. 题目链接:CF原网 洛谷 题目大意: 一个国家有 $n$ 个城市,$m$ 条有向道路组成.在这个国家一个星期有 $d$ 天,每个城市有一个博物馆. 有个旅行团在城市 $1$ 出发,当天是 ...
- CF1137C Museums Tour(tarjan+DP)
由于d很小,所以可以把每个点拆成d个点,然后对于边(x,y),连边时连接((x,i),(y,i+1))及((x,d),(y,1)).然后可以对这样连的边跑一遍tarjan缩点.然后直接暴力DP即可.不 ...
- CF1137C Museums Tour
思路 强连通分量的好题 对于每个博物馆,因为时间的限制条件,不好直接统计, 发现d很小,可以建出d层分层图,原图<u,v>的边变成<u,i>到<v,i+1>的边,& ...
- CF1137 C. Museums Tour
CF1137 C. Museums Tour 一般来说的正常思路:看到有向图的第一思路都是缩点(但是要分析一波证明强联通分量中的个体可以拼凑成整体,一般都是边和点可以经过无数次然后贡献只算一次这种类型 ...
- CF 1138 E. Museums Tour
E. Museums Tour 链接 分析: 按时间建出分层图,每个点形如(u,t),表示u在在t个时刻的点,tarjan缩点.每个强连通分量中的点都能经过,然后DAG上dp. 代码: #includ ...
- hdu3488 Tour 拆点+二分图最佳匹配
In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000) one-way r ...
- 【Codeforces 1137C】Museums Tour
Codeforces 1137 C 题意:给一个有向图,一周有\(d\)天,每一个点在每一周的某些时刻会开放,现在可以在这个图上从\(1\)号点开始随意地走,问最多能走到多少个开放的点.一个点如果重复 ...
- [CF1137]Museums Tour
link \(\text{Description:}\) 一个国家有 \(n\) 个城市,\(m\) 条有向道路组成.在这个国家一个星期有 \(d\) 天,每个城市有一个博物馆. 有个旅行团在城市 \ ...
- Codeforces 1137C Museums Tour (强连通分量, DP)
题意和思路看这篇博客就行了:https://www.cnblogs.com/cjyyb/p/10507937.html 有个问题需要注意:对于每个scc,只需要考虑进入这个scc的时间即可,其实和从哪 ...
随机推荐
- Linux内核实战(二)- 操作系统概览
不知道你有没有产生过这些疑问: 桌面上的图标到底是啥?凭啥我在鼠标上一双击,就会出来一些不可描述的画面?都是从哪里跑出来的? 凭什么我在键盘上噼里啪啦地敲,某个位置就会显示我想要的那些字符? 电脑怎么 ...
- Office2019 VOL版本 自定义安装组件
众所周知,Office VOL版本可以连接KMS服务器激活,但是office2019没有镜像可以下载,所以只能依靠Office Deployment Tool来进行操作.注:Office2019 Re ...
- 使用阿里云oss
写这篇博文的原因是公司有个项目需要用到阿里云来存放用户头像文件.后期软件安装版本也可能需要存进去,然后折腾了两天终于摸熟了一点皮毛,在这里给大家简单介绍下. 一.初识对象存储oss 1.进入阿里云控制 ...
- tp5css和js引入问题
由于以前用的是tp3.2,现在转用tp5开啊个人博客,在引入CSS和JS的时候遇到了一些坑 在3.2时期需要在路径中添加public,而在tp5中则直接引入static即可. 在config.php下 ...
- spring-boot 示例大全
spring-boot-demo Spring Boot 学习示例,将持续更新... 本项目基于spring boot 最新版本(2.1.7)实现 什么是spring-boot Spring Boot ...
- react学习(二)--元素渲染
元素用来描述你在屏幕上看到的内容: const element = <h1>Hello, world</h1>; 与浏览器的 DOM 元素不同,React 当中的元素事实上是普 ...
- 使用appscan安全扫描问题以及解决办法
最近在做安全扫描,把遇到的一些问题以及一些解决方法记录下,以备后用. 扫描软件: IBM Security AppScan Standard 规则: 17441 1. 已解密的登录请求 (高) - ...
- 当我们尝试用JavaScipt测网速
npm包地址 https://www.npmjs.com/package/network-speed-test Github地址 https://github.com/penghuwan/networ ...
- 中间件增强框架之InterceptFramework
本文讲解MOF中的InterceptFramework框架.该框架可以在应用启动过程中获取画像信息,实现应用画像数据采集和存储. 一.前言 在智能运维中,应用服务所使用的组件及JAR包等相关信息非常重 ...
- 【RabbitMQ】如何进行消息可靠投递【上篇】
说明 前几天,突然发生线上报警,钉钉连发了好几条消息,一看是RabbitMQ相关的消息,心头一紧,难道翻车了? [橙色报警] 应用[xxx]在[08-15 16:36:04]发生[错误日志异常],al ...