难度系数:1900 graphs

题意:有 n 个银行,m 个客户,每个客户都把自己的资料放在 2 个银行,一天总共有 h 小时,每个银行每天都要维护一小时,这一小时内银行无法工作,但是这一小时客户仍然可以在另一个银行提取资料,于是客户就可以一天 h 小时随时提取资料。现在要选择 k 个银行进行实验,每个进行实验的银行,它每天的维护时间都推迟一小时,如果原来的维护时间是 h−1 时,进行实验后银行的维护时间就为 0 时。问最少选择几个银行(至少一个)进行实验,才能仍然保证每一个客户随时都能提取到资料。

输入:第一行为 3 个整数n,m,h (2≤n≤105,1≤m≤1e5,2≤h≤1e5),第二行为 nn 个整数 u1,u2,⋯,un (0≤ui<h)表示第 i 个银行一天内需要维护的时间点。接下去 m行每行两个整数 ci,1,ci,2 (1≤ci,1,ci,2≤n),表示第 i 个客户把资料存放在第 ci,1 和第 ci,2 个银行。数据保证最初每一个客户都可以在一天的任意时刻取得资料。

解法:其实想想也能知道转化成图论关系,但是怎么建边呢?我们可以知道如果(p[u]+1)%h==p[v],就能在u和v之间建立一个单向边,add(u,v);同样,如果(p[v]+1)%h==p[u],就能在v和u之间建立一个单向边,add(v,u)。记住建边的时候不要用 else if,因为有一组数据卡的条件是回路只有2个点...既然知道了建边的关系了,那么我们就可以利用Tarjan强联通的缩点方法把它缩成id[i],这个时候统计一下每个id[i]的outdeg有几个;我们寻找答案的方法是:1~n中,outdeg[id[i]]为0,且num[id[i]]最小。那么其实这个问题说到这个地步也算是比较简单了。感觉想想还是挺容易的,就是坑点有点多吧。。。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '\n'
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+;
const int maxn=1e5+;
int tot,head[maxn];
struct E{
int to,next;
}edge[maxn<<];
void add(int u,int v){
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
}
int n,m,h,p[maxn],dfn[maxn],low[maxn],vis[maxn],id[maxn],num[maxn],tott,cnt=;
stack<int> s;
void tarjan(int x){
low[x]=dfn[x]=++tott;
s.push(x);vis[x]=;
for(int i=head[x];i!=-;i=edge[i].next){
int v=edge[i].to;
if(!dfn[v]){
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(vis[v]){
low[x]=min(low[x],dfn[v]);
}
}
if(low[x]==dfn[x]){
cnt++;
while(){
int now=s.top();s.pop();
vis[now]=;
id[now]=cnt;
num[cnt]+=;
if(now==x) break;
}
}
}
int out[maxn];vector<int> G[maxn];
int main(){
cin>>n>>m>>h;mem(head,-);
rep(i,,n) cin>>p[i];
while(m--){
int u,v;cin>>u>>v;
if((p[u]+)%h==p[v]) add(u,v);
if((p[v]+)%h==p[u]) add(v,u);
}
rep(i,,n){
if(!dfn[i]) tarjan(i);
}
for(int i=;i<=n;i++){
for(int j=head[i];j!=-;j=edge[j].next){
if(id[i]!=id[edge[j].to]){
G[id[i]].push_back(id[edge[j].to]);
out[id[i]]+=;
}
}
}
int ans=INF,cur;
for(int i=;i<=cnt;i++){
if(out[i]==){
ans=min(ans,num[i]);
if(num[i]==ans) cur=i;
}
}
vector<int> vec;
for(int i=;i<=n;i++){
if(id[i]==cur){
vec.push_back(i);
}
}
cout<<ans<<endl;
for(int i=;i<vec.size();i++){
cout<<vec[i]<<" ";
}
puts("");
}

 

Codeforces 949C(Data Center Maintenance,Tarjan缩点)的更多相关文章

  1. codeforces 949C - Data Center Maintenance【tarjan】

    首先转换图论模型,把某个客户一个终端的维修时间(+1)%h之后和另一个终端维修时间一样,这样的两个终端连一条有向边,表示推后一个终端就必须推后另一个 然后tarjan缩点,一个scc里的终端是要一起推 ...

  2. Codeforces 950E Data Center Maintenance ( 思维 && 强连通分量缩点 )

    题意 : 给出 n 个点,每个点有一个维护时间 a[i].m 个条件,每个条件有2个点(x,y)且 a[x] != a[y].选择最少的 k (最少一个)个点,使其值加1后,m个条件仍成立. 分析 : ...

  3. CF 949C Data Center Maintenance——思路+SCC

    题目:http://codeforces.com/contest/949/problem/C 可以想到可能是每组c有连边的可能. 但别直接给c1.c2连边,那样之后会变得很不好做. 可以把一些限制放在 ...

  4. Codeforces 950E Data Center Maintenance 强连通分量

    题目链接 题意 有\(n\)个信息中心,每个信息中心都有自己的维护时间\((0\leq t\lt h)\),在这个时刻里面的信息不能被获得. 每个用户的数据都有两份备份,放在两个相异的信息中心(维护时 ...

  5. Codeforces 950.E Data Center Maintenance

    E. Data Center Maintenance time limit per test 1 second memory limit per test 512 megabytes input st ...

  6. Codeforces Round #469 (Div. 1) 949C C. Data Center Maintenance (Div. 2 950E)

    题 OvO http://codeforces.com/contest/949/problem/C codeforces 949C 950E 解 建图,记原图为 G1,缩点,记缩完点后的新图为G2 缩 ...

  7. Codeforces Round #469 (Div. 2) E. Data Center Maintenance

    tarjan 题意: 有n个数据维护中心,每个在h小时中需要1个小时维护,有m个雇主,他们的中心分别为c1,c2,要求这两个数据中心不能同时维护. 现在要挑出一个数据中心的子集,把他们的维护时间都推后 ...

  8. codeforce469DIV2——E. Data Center Maintenance

    题意: 有n个数据中心,m个客户,每天有h个小时,其中 n,m,h<=100000.每个数据中心i每天都会有一个数据维护的时间0<=u[i]<=h-1,在数据中心维护期间时不可以使用 ...

  9. Data Center Maintenance CodeForces - 950E

    http://codeforces.com/contest/950/problem/E 贴一份板子 #include<cstdio> #include<vector> #inc ...

随机推荐

  1. Mysql基础练习--实例

    修改字段名:alter table 表名 change 旧字段名 新字段名 新数据类型;--- 主键 ------------------------------------------------- ...

  2. Java 解析 xml 常见的4中方式:DOM SAX JDOM DOM4J

    Java 四种解析 XML 的特点 1.DOM 解析: 形成了树结构,有助于更好的理解.掌握,且代码容易编写. 解析过程中,树结构保存在内存中,方便修改. 2.SAX 解析: 采用事件驱动模式,对内存 ...

  3. JQ获取select上的option的data-start和data-id

    来源:https://zhidao.baidu.com/question/692142321436883524.html 静态的写法: 用jq的attr()函数,如: HTML: <select ...

  4. python字符串 提取括号中的内容

    返回值是一个列表 re.findall(r'[(](.*?)[)]', str1)

  5. thymeleaf 模板语法

    模板语法 如何在 script 标签体内部使用 th 获取后端数据 添加如下属性 <script type="text/javascript" th:inline=" ...

  6. Spring Cloud 系列之 Stream 消息驱动(二)

    本篇文章为系列文章,未读第一集的同学请猛戳这里:Spring Cloud 系列之 Stream 消息驱动(一) 本篇文章讲解 Stream 如何实现消息分组和消息分区. 消息分组 如果有多个消息消费者 ...

  7. Google Play商店为预注册的游戏和应用提供自动安装功能

    谷歌 Play 商店一直在准备一项功能,它可以自动安装用户预先注册的应用程序和游戏.似乎该功能现已开始向第一批用户推出.有些人在预注册时会看到一个新选项,使他们能够利用发布时自动安装的功能. 用户在 ...

  8. 从实践出发:微服务布道师告诉你Spring Cloud与Boot他如何选择

    背景 随着公司业务量的飞速发展,平台面临的挑战已经远远大于业务,需求量不断增加,技术人员数量增加,面临的复杂度也大大增加.在这个背景下,平台的技术架构也完成了从传统的单体应用到微服务化的演进. 系统架 ...

  9. Docker容器利用weave实现跨主机互联

    Docker容器利用weave实现跨主机互联 环境: 实现目的:实现主机A中容器1与主机B中容器1的网络互联 主机A步骤: ①下载复制weave二进制执行文件(需要internet)[root@192 ...

  10. 洛谷2014 选课(树形DP)树形背包问题

    题目描述 在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习.现在有N门功课,每门课有个学分,每门课有一 ...