zoukankan      html  css  js  c++  java
  • 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

      缩完点后的图 G2 必定无环,求这个无环图 G2 中每个点的入度,

      找出入度0 的那些点,记这些点的集合为 S,然后把 S 中这些点映射到 G1 中,则这些点各自对应一个点集。的各点中,对应的最小集合即为所求集合

    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <stack>
    
    using namespace std;
    
    const int N=100044;  
    const int INF=1e9+44;
    
    struct data  
    {  
        int to,next;  
    } tu[N*2];  
    
    struct sav
    {
    	int a,b;
    } edgsav[N*2];
    
    int head[N];  
    int ip;  
    int dfn[N], low[N];///dfn[]表示深搜的步数,low[u]表示u或u的子树能够追溯到的最早的栈中节点的次序号  
    int sccno[N];///缩点数组,表示某个点对应的缩点值  
    int step;  
    int scc_cnt;///强连通分量个数  
    int n,m,h,u[N];
    int ind[N],outd[N];
    int edgnum;
    
    void init()  
    {  
        ip=0;  
        edgnum=0;
        memset(head,-1,sizeof(head));  
        memset(ind,0,sizeof(ind));
        memset(outd,0,sizeof(outd));
    }  
    
    void add(int u,int v)  
    {  
    	edgnum++,edgsav[edgnum].a=u,edgsav[edgnum].b=v;
        tu[ip].to=v,tu[ip].next=head[u],head[u]=ip++;  
    }  
    
    vector<int> scc[N];///得出来的缩点,scc[i]里面存i这个缩点具体缩了哪些点  
    stack<int> S;  
    
    void dfs(int u)  
    {  
        dfn[u] = low[u] = ++step;  
        S.push(u);  
        for (int i = head[u]; i !=-1; i=tu[i].next)  
        {  
            int v = tu[i].to;  
            if (!dfn[v])  
            {  
                dfs(v);  
                low[u] = min(low[u], low[v]);  
            }  
            else if (!sccno[v])  
                low[u] = min(low[u], dfn[v]);  
        }  
        if (low[u] == dfn[u])  
        {  
            scc_cnt += 1;  
            scc[scc_cnt].clear();  
            while(1)  
            {  
                int x = S.top();  
                S.pop();  
                if (sccno[x] != scc_cnt) scc[scc_cnt].push_back(x);  
                sccno[x] = scc_cnt;  
                if (x == u) break;  
            }  
        }  
    }  
    
    void tarjan(int n)  
    {  
        memset(sccno, 0, sizeof(sccno));  
        memset(dfn, 0, sizeof(dfn));  
        step = scc_cnt = 0;  
        for (int i = 1; i <=n; i++)  
            if (!dfn[i]) dfs(i);  
    }  
    
    inline int trans(int x)
    {
    	return (x+1)%h;
    } 
    
    int main()
    {
    	int a,b;
    	init();
    	scanf("%d%d%d",&n,&m,&h);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&u[i]);
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d",&a,&b);
    		if(trans(u[a])==u[b]) add(a,b);
    		if(trans(u[b])==u[a]) add(b,a);
    	}
    	tarjan(n);
    	for(int i=1;i<=edgnum;i++)
    		if(sccno[edgsav[i].a]!=sccno[edgsav[i].b])
    		{
    			outd[sccno[edgsav[i].a]]++;
    			ind[sccno[edgsav[i].b]]++;
    		}
    	int the,tmp=INF;
    	for(int i=1;i<=scc_cnt;i++)
    		if(outd[i]==0 && scc[i].size()<tmp)
    			the=i,tmp=scc[i].size();
    	printf("%d
    ",tmp);
    	for(int i=0;i<scc[the].size();i++)
    	{
    		printf("%d",scc[the][i]);
    		if(i==scc[the].size()-1) puts("");
    		else printf(" ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    行政区划代码和关键字提取
    清洗数据之地理纬度
    第三周学习进度
    性能战术在代码中的体现
    第二周学习进度
    淘宝网-质量属性场景
    如何做一名好的软件架构师
    寒假学习笔记16
    寒假学习笔记15
    寒假学习笔记14
  • 原文地址:https://www.cnblogs.com/FxxL/p/8536001.html
Copyright © 2011-2022 走看看