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

分析 : 

发现改变某些数加一后可能产生联动效应

换句话说就是改变某些数则必须改变另一些数来维持 m 个条件的成立

这个可以用图来表示,对于给出来的每一个 (x, y) 如果改变 x 后等于 y 则连 x => y 边

表示要改变 x 则必须改变 y,然后对于 y 进行同样的判断是否连边

最后建完图后,若有成环的,则这个环上的点要加一改变,则环上所有点都必须进行改变

因此将整个图进行强连通分量缩点,最后考察所有出度为 0 的的分量,哪个分量点最少

则这个点集就是答案,出度不为 0 的点肯定不是最优的,因为这些点定会回到出度为 0 的点

#include<bits/stdc++.h>
using namespace std;
;
;
struct EDGE{ int v, nxt; }Edge[maxm];
int Head[maxn], cnt;
int DFN[maxn], LOW[maxn], color[maxn], INDEX, id;
bool vis[maxn], out[maxn];
stack<int> stk;
vector<int> num[maxn];
int N, M, H;

inline void init()
{
    while(!stk.empty()) stk.pop();
    ; i<=N; i++){
        Head[i] = DFN[i] = LOW[i] = color[i] = -;
        out[i] = false;
       num[i].clear();
    }cnt = INDEX = id = ;
}

inline void AddEdge(int from, int to)
{
    Edge[cnt].v = to;
    Edge[cnt].nxt = Head[from];
    Head[from] = cnt++;
}

inline void tarjan(int u)
{
    DFN[u] = LOW[u] = INDEX++;
    stk.push(u);
    vis[u] = true;
    ; i=Edge[i].nxt){
        int Eiv = Edge[i].v;
        ){
            tarjan(Eiv);
            LOW[u] = min(LOW[u], LOW[Eiv]);
        }else{
            if(vis[Eiv])
                LOW[u] = min(LOW[u], LOW[Eiv]);
        }
    }

    if(DFN[u] == LOW[u]){
        color[u] = ++id;
        num[id].push_back(u);;
        vis[u] = false;
        while(stk.top() != u){
            vis[stk.top()] = false;
            color[stk.top()] = id;
            num[id].push_back(stk.top());
            stk.pop();
        }
        stk.pop();
    }
}

int arr[maxn];
int main(void)
{
    scanf("%d %d %d", &N, &M, &H);

    init();

    ; i<=N; i++)
        scanf("%d", &arr[i]);

    int u, v;
    while(M--){
        scanf("%d %d", &u, &v);
        )%H == arr[v]) AddEdge(u, v);
        )%H == arr[u]) AddEdge(v, u);
    }

    ; i<=N; i++)
        )
            tarjan(i);///强连通分量缩点

    ; i<=id; i++){///统计缩点后每个点的出入度情况
        ; j<num[i].size(); j++){
            u = num[i][j];
            ; k=Edge[k].nxt){
                int Eiv = Edge[k].v;
                if(color[Eiv] != i){
                    out[i] = true;
                    break;
                }
            }
            if(out[i]) break;
        }
    }

    int MM = 0x3f3f3f3f, which;
    ; i<=id; i++){
        if(!out[i] && num[i].size() < MM){
            MM = num[i].size();
            which = i;
        }
    }

    printf("%d\n", MM);
    ; i<=N; i++)
        if(color[i] == which)
            printf("%d ", i);
    puts("");
    ;
}

Codeforces 950E Data Center Maintenance ( 思维 && 强连通分量缩点 )的更多相关文章

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

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

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

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

  3. Codeforces 949C(Data Center Maintenance,Tarjan缩点)

    难度系数:1900 graphs 题意:有 n 个银行,m 个客户,每个客户都把自己的资料放在 2 个银行,一天总共有 h 小时,每个银行每天都要维护一小时,这一小时内银行无法工作,但是这一小时客户仍 ...

  4. Codeforces 950.E Data Center Maintenance

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

  5. POJ1236Network of Schools[强连通分量|缩点]

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16571   Accepted: 65 ...

  6. POJ1236Network of Schools(强连通分量 + 缩点)

    题目链接Network of Schools 参考斌神博客 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后 ...

  7. HD2767Proving Equivalences(有向图强连通分量+缩点)

    题目链接 题意:有n个节点的图,现在给出了m个边,问最小加多少边是的图是强连通的 分析:首先找到强连通分量,然后把每一个强连通分量缩成一个点,然后就得到了一个DAG.接下来,设有a个节点(每个节点对应 ...

  8. UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)

    题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...

  9. ZOJ3795 Grouping(强连通分量+缩点+记忆化搜索)

    题目给一张有向图,要把点分组,问最少要几个组使得同组内的任意两点不连通. 首先考虑找出强连通分量缩点后形成DAG,强连通分量内的点肯定各自一组,两个强连通分量的拓扑序能确定的也得各自一组. 能在同一组 ...

随机推荐

  1. css实现毛玻璃效果

    css实现毛玻璃效果,效果图 1,html代码 <div class="mainHolder"> <div class="textHolder" ...

  2. 第六周课程总结&试验报告(四)

    一.实验目的 (1)掌握类的继承方法 (2)变量的继承和覆盖,方法的继承,重载和覆盖实现 二.实验内容 三.实验过程 1. 实验源码 package test; import java.util.Sc ...

  3. spring boot-13.数据访问

    1.spring boot 的自动配置提供的方便快捷的数据库操作服务,只需要进行少量配置即可连接数据库.spring boot 在org.springframework.boot.autoconfig ...

  4. 写 JSP 的痛点,真的非常痛!

    一.前戏 前后端分离已成为互联网项目开发的业界标准使用方式,通过nginx+tomcat的方式(也可以中间加一个nodejs)有效的进行解耦,并且前后端分离会为以后的大型分布式架构.弹性计算架构.微服 ...

  5. javaSE温习一&二

    这是一个简单的笔记 涉及到常量.变量:流程控制语句.数组:类与对象.封装.构造方法:Scanner类.Random类.Arraylist类: 1.pubic class  static void 2. ...

  6. C++中的三种继承方式

    1,被忽略的细节: 1,冒号( :)表示继承关系,Parent 表示被继承的类,public 的意义是什么? class Parent { }; class Child : public Parent ...

  7. js知识点——1

    onload 事件会在页面或图像加载完成后立即发生. document.write("内容")将在加载页面时输出 内容可以是什么,可以是一个标签,它输出的文件不能自动换行: < ...

  8. PHP 识别获取身份证号代表的信息

    18位的身份证号每一位都代表什么 例如:110102197810272321 echo substr(110102197810272321,0,2)."<br>"; / ...

  9. 内核中likely和unlikely宏定义

    在内核代码中经常会看到unlikely和likely的踪影.他们实际上是定义在 linux/compiler.h 中的两个宏. #define likely(x)    __builtin_expec ...

  10. msql 事务

    START TRANSACTION      delete from t_emp    delete from t_deptcommit START TRANSACTION delete from t ...