• CF949 C Data Center Maintenance——边双连通分量


    题目:http://codeforces.com/contest/949/problem/C

    把一个点指向修改它会影响到的点就可以做了;

    有取模,所以多出一些要注意的地方,首先是可能出现环,所以需要 tarjan 求边双;

    其次,边集数组的大小应该开成两倍,因为取模可能导致一对 ci 互相连边;

    然后找出不影响别的点的、最小的边双,输出即可;

    而我竟然把 tarjan 都少写了一个 top-- !真是对自己无语了...

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    using namespace std;
    int const maxn=1e5+5;
    int n,m,h,a[maxn],hd[maxn],cr,ct,col[maxn],sta[maxn],top,dfn[maxn],low[maxn],tim,deg[maxn];
    bool vis[maxn];
    vector<int>scc[maxn];
    struct N{
        int to,nxt;
        N(int t=0,int n=0):to(t),nxt(n) {}
    }ed[maxn<<1];
    void add(int x,int y){ed[++ct]=N(y,hd[x]); hd[x]=ct;}
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tim; sta[++top]=x; vis[x]=1;
        for(register int i=hd[x];i;i=ed[i].nxt)
        {
            int u=ed[i].to;
            if(!dfn[u])
            {
                tarjan(u); low[x]=min(low[x],low[u]);
            }
            else if(vis[x])low[x]=min(low[x],dfn[u]);
        }
        if(low[x]==dfn[x])
        {
            cr++;
            while(sta[top]!=x)
            {
                int y=sta[top]; top--;
                vis[y]=0; col[y]=cr;
                scc[cr].push_back(y);
            }
            top--;//!
            vis[x]=0; col[x]=cr; scc[cr].push_back(x);
        }
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&h);
        for(register int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(register int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            if((a[x]+1)%h==a[y])add(x,y);
            if((a[y]+1)%h==a[x])add(y,x);
        }
        for(register int i=1;i<=n;i++)
            if(!dfn[i])tarjan(i);
        for(register int i=1;i<=n;i++)
            for(register int j=hd[i];j;j=ed[j].nxt)
            {
                int u=ed[j].to;
                if(col[i]!=col[u])deg[col[i]]++;
            }
        int mn=0x3f3f3f3f,tag;
        for(register int i=1;i<=cr;i++)
            if(!deg[i]&&scc[i].size()<mn)mn=scc[i].size(),tag=i;
        printf("%d
    ",scc[tag].size());
        for(register int j=0;j<scc[tag].size();j++)
            printf("%d ",scc[tag][j]);
        return 0;
    }
  • 相关阅读:
    C#实现简单的委托异步调用
    jquery each遍历节点使用
    js操作document文档元素 节点交换交换
    js闭包使用
    .net下各个数据类型所占用的字节
    html file控件选择文件后立即预览 js实现
    叉积运用-判断凸多边形
    高精度算法-大数加法
    Dfs学习经验(纸上运行理解DFS)【两道题】
    a标签点击后更改颜色
  • 原文地址:https://www.cnblogs.com/Zinn/p/9278731.html
Copyright © 2020-2023  润新知