题目链接

题意

有\(n\)个信息中心,每个信息中心都有自己的维护时间\((0\leq t\lt h)\),在这个时刻里面的信息不能被获得。

每个用户的数据都有两份备份,放在两个相异的信息中心(维护时间也相异)。

现要挑选出信息中心的一个尽量小的子集,使得将这个子集的维护时间向后推移一个小时后,不会导致问题(存在一个用户,其数据所在的两个信息中心维护时间相同)。

思路

强连通分量

考虑每个用户的信息存放的两个信息中心,\(u,v\):

如果调整其中任何一个的时间不会导致与另外一个产生冲突,就说明是安全的;

否则若\(u\)调整后与\(v\)产生冲突,则一旦调整\(u\)就必须调整\(v\),于是加一条边\(<u,v>\).

在得到的图上跑\(tarjan\)再缩点后得到强连通分量,答案就是新的图中 出度为\(0\)的并且\(size\)最小 的一块\(SCC\)。道理显然。

Code

#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define maxn 100010
using namespace std;
typedef long long LL;
int dfn[maxn], low[maxn], ne[maxn], belong[maxn], a[maxn], sz[maxn], scc, cnt, tot, outd[maxn];
stack<int> s;
bool in[maxn];
struct Edge { int from, to, ne; }edge[maxn<<1];
void add(int u, int v) {
edge[tot] = {u, v, ne[u]};
ne[u] = tot++;
}
void tarjan(int u) {
dfn[u] = low[u] = ++cnt;
in[u] = true;
s.push(u);
for (int i = ne[u]; ~i; i = edge[i].ne) {
int v = edge[i].to;
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (in[v]) low[u] = min(low[u], dfn[v]);
}
if (low[u]==dfn[u]) {
++scc;
while (true) {
int v = s.top(); in[v] = false; s.pop();
belong[v] = scc; ++sz[scc];
if (u==v) break;
}
}
}
void contrast() {
F(i, 0, tot) {
int u = edge[i].from, v = edge[i].to;
if (belong[u]==belong[v]) continue;
++outd[belong[u]];
}
}
int main() {
memset(ne, -1, sizeof ne);
int n, m, h, u, v;
scanf("%d%d%d", &n, &m, &h);
F2(i, 1, n) scanf("%d", &a[i]);
F(i, 0, m) {
scanf("%d%d", &u,&v);
if (a[u]>a[v]) swap(u, v);
if (a[v]-a[u]==1) add(u, v);
if (a[v]-a[u]==h-1) add(v, u);
}
F2(i, 1, n) if (!dfn[i]) tarjan(i);
contrast();
int ans=n+1, p=-1;
F2(i, 1, scc) {
if (!outd[i]) {
if (sz[i]<ans) ans=sz[i], p=i;
}
}
printf("%d\n", ans);
F2(i, 1, n) if (belong[i]==p) printf("%d ", i); puts("");
return 0;
}

最新文章

  1. Android数据加密之异或加密算法
  2. jQuery选择器笔记
  3. Coding道场:第一次
  4. [C#] 使用NPOI将Datatable保存到Excel
  5. 一些sql三
  6. 济南学习D2T1__折纸带
  7. Javascript小笔记
  8. CentOS6.X安装vsftpd服务
  9. jquery对象与js对象的相互转换
  10. scaletype
  11. Java排序算法之堆排序
  12. 主流nosql数据库对比
  13. centos7 编译安装greenplum5.7
  14. Scala依赖注入
  15. 使用Visual Studio Team Services敏捷规划和项目组合管理(三)——使用Kanban板
  16. hive字符函数
  17. [原]Jenkins(二十一) jenkins再出发Build periodically和Poll SCM
  18. linux命令学习:PATH and LDFLAGS and CFLAGS
  19. Helm一:简介
  20. awk 调用 shell 命令,并传递参数

热门文章

  1. OpenCV入门:(二:加载,显示,修改以及保存图片)
  2. Python-类-函数参数-takes 0 positional arguments but 1 was given
  3. Qt编译出错:During startup program exited with code 0xc0000135
  4. Sublime Text 3配置 Python3 开发环境
  5. 平衡二叉树(AVL Tree)
  6. Linux 简单socket实现TCP通信
  7. 安装floodlight遇到的问题和解决
  8. window下对samba的清理操作
  9. Chromium之各国语言切换
  10. 推荐一个好的Redis GUI 客户端工具