Codeforces 949C(Data Center Maintenance,Tarjan缩点)
难度系数: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缩点)的更多相关文章
- codeforces 949C - Data Center Maintenance【tarjan】
首先转换图论模型,把某个客户一个终端的维修时间(+1)%h之后和另一个终端维修时间一样,这样的两个终端连一条有向边,表示推后一个终端就必须推后另一个 然后tarjan缩点,一个scc里的终端是要一起推 ...
- Codeforces 950E Data Center Maintenance ( 思维 && 强连通分量缩点 )
题意 : 给出 n 个点,每个点有一个维护时间 a[i].m 个条件,每个条件有2个点(x,y)且 a[x] != a[y].选择最少的 k (最少一个)个点,使其值加1后,m个条件仍成立. 分析 : ...
- CF 949C Data Center Maintenance——思路+SCC
题目:http://codeforces.com/contest/949/problem/C 可以想到可能是每组c有连边的可能. 但别直接给c1.c2连边,那样之后会变得很不好做. 可以把一些限制放在 ...
- Codeforces 950E Data Center Maintenance 强连通分量
题目链接 题意 有\(n\)个信息中心,每个信息中心都有自己的维护时间\((0\leq t\lt h)\),在这个时刻里面的信息不能被获得. 每个用户的数据都有两份备份,放在两个相异的信息中心(维护时 ...
- Codeforces 950.E Data Center Maintenance
E. Data Center Maintenance time limit per test 1 second memory limit per test 512 megabytes input st ...
- 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 缩 ...
- Codeforces Round #469 (Div. 2) E. Data Center Maintenance
tarjan 题意: 有n个数据维护中心,每个在h小时中需要1个小时维护,有m个雇主,他们的中心分别为c1,c2,要求这两个数据中心不能同时维护. 现在要挑出一个数据中心的子集,把他们的维护时间都推后 ...
- codeforce469DIV2——E. Data Center Maintenance
题意: 有n个数据中心,m个客户,每天有h个小时,其中 n,m,h<=100000.每个数据中心i每天都会有一个数据维护的时间0<=u[i]<=h-1,在数据中心维护期间时不可以使用 ...
- Data Center Maintenance CodeForces - 950E
http://codeforces.com/contest/950/problem/E 贴一份板子 #include<cstdio> #include<vector> #inc ...
随机推荐
- SpringBoot word 转换为 pdf
转换文件 swagger 地址, 基于 SpringBoot 开发 http://119.27.167.41:8888/convertor/swagger-ui.html 带有图片的word 转换体验 ...
- SpringMVC视图解析中的 forward: 与 redirect: 前缀
在 SpringMVC 中,可以指定画面的跳转方式.使用 forward: 前缀实现请求转发跳转,使用 redirect: 前缀实现重定向跳转.有前缀的转发和重定向操作和配置的视图解析器没有关系,视图 ...
- Matplotlib 误差线的绘制和子图的创建方式
一.绘制误差线 使用errorbar方法可以绘制误差线. x = np.linspace(0,10,50) dy=0.8 y = np.cos(x) + dy*np.random.randn(50) ...
- linux下的.ssh文件夹路径等
1.linux下的.ssh文件夹在~下,直接cd ~/.ssh即可 2.tp经过gd类处理过的水印图片格式为png 3.前端扒下别人家的网站如果自己本地打开有出现相同的代码段则有可能是js动态添加的, ...
- 【shell】shell脚本入门
1. 前言 1.1 为什么学习shell编程 Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具,Linux/UNIX系统的底层及基础应用软件的核心大部分涉及Shell脚 ...
- axios的使用小技巧:如何绕过字符串拼接,直接传递对象
Vue.js官方推荐使用axios作为发送http请求的工具,在使用axios中,有些小技巧是不容易发现的.当我们不知道这些技巧时,我们可能会使用其他"奇技淫巧",比如,我们很容 ...
- [CodeForces-259C] Little Elephant and Bits
C. Little Elephant and Bits time limit per test 2 seconds memory limit per test 256 megabytes input ...
- bzoj4318 OSU!和bzoj 3450 Tyvj1952 Easy
这俩题太像了 bzoj 3450 Tyvj1952 Easy Description 某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:( 我们来简化一下这个游戏的规则 有n次点 ...
- nnIPXougCC
13:58:31 2020-03-14 发现一本书叫做<活法> 学习ing 2020-03-14 15:22:36 太快 ,练习了一会sql语句和打字 想看一会 憨豆特 ...
- nginx常见应用实例
1.nginx 中 location 应用实例location 是 nginx 的精华,nginx 就是通过拦截到的请求去对配置好的 location 块(location block)进行请求代理的 ...