tarjan

题意: 有n个数据维护中心,每个在h小时中需要1个小时维护,有m个雇主,他们的中心分别为c1,c2,要求这两个数据中心不能同时维护。

现在要挑出一个数据中心的子集,把他们的维护时间都推后一个小时。问最小推几个?

 

建图,如果对于一个顾客,两个数据维护中心维护时间正好差一个小时,那么前者向后者连一条边。在一个强连通分量里面的所有点必须选。。如果有连向其他的强连通分量,那么那个也必须选,这种情况肯定不是最优,所以舍弃所有有出度的强连通分量。

 

tarjan缩点,然后判一判。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#define LL long long
using namespace std;
const int inf = 0x3f3f3f3f;
const LL LLinf = 0x3f3f3f3f3f3f3f3f;
LL read()
{
LL x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10ll+ch-'0';ch=getchar();}
return x*f;
} const int maxn = 100000 + 10;
const int maxm = 200000 + 10; struct Edge {
int to,nex;
}e[maxm]; int n,m,h;
int u[maxn];
int g[maxn],eid; void addedge(int a,int b) {
e[eid]=(Edge){b,g[a]}; g[a]=eid++;
} void build()
{
n=read(); m=read(); h=read();
for(int i=1;i<=n;i++)
{
u[i]=read();
} memset(g,-1,sizeof(g));
for(int i=1,c1,c2;i<=m;i++)
{
c1=read(); c2=read();
if((u[c1]+1)%h==u[c2])
{
addedge(c1,c2);
//printf(" %d %d\n",c1,c2);
}
if((u[c2]+1)%h==u[c1])
{
addedge(c2,c1);
//printf(" %d %d\n",c2,c1);
}
}
} int dfn[maxn],low[maxn],cnt;
bool instack[maxn];
int s[maxn],sp;
int color[maxn],cp;
int sum[maxn];
int out[maxn];
int res; void tarjan(int u)
{
dfn[u]=low[u]=++cnt;
s[++sp]=u; instack[u]=1; for(int i=g[u];~i;i=e[i].nex)
{
if(!dfn[e[i].to])
{
tarjan(e[i].to);
low[u]=min(low[u],low[e[i].to]);
}
else if(instack[e[i].to])
{
low[u]=min(low[u],dfn[e[i].to]);
}
} if(dfn[u]==low[u]) {
++cp; int v;
while(sp)
{
v=s[sp];
instack[v]=0;
color[v]=cp;
sum[cp]++;
sp--;
if(s[sp+1]==u) break;
}
}
} void solve()
{
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
/*
for(int i=1;i<=n;i++)
printf("color[%d]=%d\n",i,color[i]);
*/
/*for(int i=1;i<=n;i++)
if(!color[i])
{
color[i]=++cp;
sum[i]=1;
}
*/
for(int u=1;u<=n;u++) { for(int i=g[u];~i;i=e[i].nex) if(color[e[i].to]!=color[u])
out[color[u]]++;
} res=0; sum[0]=inf;
for(int i=1;i<=cp;i++) {
//printf("Test %d %d\n",i,out[i]);
if(out[i]==0&&sum[i]<sum[res])
{
res=i;
}
}
printf("%d\n",sum[res]);
for(int i=1;i<=n;i++) if(color[i]==res)
printf("%d ",i);
printf("\n");
} int main()
{
build();
solve(); return 0;
}

Codeforces Round #469 (Div. 2) E. Data Center Maintenance的更多相关文章

  1. Codeforces Round #296 (Div. 1) C. Data Center Drama 欧拉回路

    Codeforces Round #296 (Div. 1)C. Data Center Drama Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: xx ...

  2. Codeforces Round #469 (Div. 2)

    Codeforces Round #469 (Div. 2) 难得的下午场,又掉分了.... Problem A: 怎么暴力怎么写. #include<bits/stdc++.h> #de ...

  3. Codeforces Round #469 Div. 2 A B C D E

    A. Left-handers, Right-handers and Ambidexters 题意 \(l\)个左撇子,\(r\)个右撇子,\(a\)个两手均可.要组成一支队伍,里面用左手的人数与用右 ...

  4. Codeforces Round #469 Div. 2题解

    A. Left-handers, Right-handers and Ambidexters time limit per test 1 second memory limit per test 25 ...

  5. 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 缩 ...

  6. Codeforces Round #469 (Div. 2)C. Zebras(思维+模拟)

    C. Zebras time limit per test memory limit per test 512 megabytes input standard input output standa ...

  7. Codeforces Round #469 (Div. 2) F. Curfew

    贪心 题目大意,有2个宿管分别从1和n开始检查房间,记录人数不为n的房间个数,然后锁住房间. 没有被锁的房间中的学生可以选择藏在床底,留在原地,或者转移(最远转移d个房间)   然后抄了网上大神的代码 ...

  8. Codeforces Round #378 (Div. 2) D题(data structure)解题报告

    题目地址 先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA).做到C题时看到题目情况非常 ...

  9. 【codeforces】【比赛题解】#950 CF Round #469 (Div. 2)

    剧毒比赛,至少涨了分对吧.: ( [A]Left-handers, Right-handers and Ambidexters 题意: 有\(l\)个右撇子,\(r\)个左撇子,\(a\)个双手都惯用 ...

随机推荐

  1. CLR via c#读书笔记九:接口

    1.接口对一组方法签名进行了统一命名.接口还能定义事件.无参属性和有参属性(C#的索引器). 2.c#禁止接口定义任何一种静态成员. 3.C#编译器要求将实现接口的方法标记为public.CLR要求将 ...

  2. vim 安装

    Ubuntu 16.04 下 Vim安装及配置 默认已经安装了VIM-tiny linuxidc@linuxidc:~$ locate vi | grep 'vi$' |xargs ls -al lr ...

  3. 40套PSD欧美扁平化网页模板,可二次编辑开发,精品

    40套PSD欧美扁平化网页模板,可二次编辑开发,绝对精品,下载地址:百度网盘, https://pan.baidu.com/s/1uMF4MM_3UC2Q6mbyNomLfQ 模板内容预览:   小

  4. 「日常训练」Kefa and Company(Codeforces Round #321 Div. 2 B)

    题意与分析(CodeForces 580B) \(n\)个人,告诉你\(n\)个人的工资,每个人还有一个权值.现在从这n个人中选出m个人,使得他们的权值之和最大,但是对于选中的人而言,其他被选中的人的 ...

  5. C++11 type_traits 之is_pointer,is_member_function_pointer源码分析

    源码如下: template<typename> struct __is_pointer_helper : public false_type { }; template<typen ...

  6. [HNOI2018]转盘

    [HNOI2018]转盘 给你一个 \(n\) 元环, 你可以在 \(0\) 时刻从任意一个位置出发, 每一秒可以选择往后或者留在原地每个点有个参数 \(T_i\) , 当你走到 \(i\) 的时间 ...

  7. python—IDLE的shell上下翻看历史

    Alt+p和Alt+n,分别向上(history previous)和向下(history next)调出使用过的历史命令.

  8. 开源自动驾驶仿真平台 AirSim (1) - Unreal Engine

    AirSim 官方Github: https://github.com/Microsoft/AirSim AirSim 是微软的开源自动驾驶仿真平台(其实它还能做很多事情,这里主要用于自动驾驶仿真研究 ...

  9. ubuntu下Nodic开发环境搭建

    ubuntu下Nodic开发环境搭建 1.编译环境 ubuntu可直接装gcc编译环境 sudo apt install gcc-arm-none-eabi 也可以下载可执行文件download 2. ...

  10. HDU 3467 Song of the Siren(圆交)

    Problem Description In the unimaginable popular DotA game, a hero Naga Siren, also known as Slithice ...