• 洛谷P2835 刻录光盘


    传送门

    题目大意:有光盘可以传着看,问最少从哪几个人分发,能全部传一遍。

    题解:缩点后求入度为0的点的个数

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 22000
    using namespace std;
    
    int n,sumedge,sumclr,top,tim,ans;
    int Stack[maxn],instack[maxn],low[maxn],dfn[maxn],bel[maxn],rd[maxn],head[maxn];
    
    struct Edge{
        int x,y,nxt;
        Edge(int x=0,int y=0,int nxt=0):
            x(x),y(y),nxt(nxt){}
    }edge[maxn<<1];
    
    void add(int x,int y){
        edge[++sumedge]=Edge(x,y,head[x]);
        head[x]=sumedge;
    }
    
    void Tarjian(int x){
        Stack[++top]=x;instack[x]=true;
        low[x]=dfn[x]=++tim;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(instack[v])low[x]=min(low[x],dfn[v]);
            else if(!dfn[v]){
                Tarjian(v);
                low[x]=min(low[x],low[v]);
            }
        }
        if(low[x]==dfn[x]){
            sumclr++;
            while(Stack[top+1]!=x){
                bel[Stack[top]]=sumclr;
                instack[Stack[top]]=false;
                top--;
            }
        }
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int x;
            while(1){
                scanf("%d",&x);
                if(!x)break;
                add(i,x);
            }
        }
        for(int i=1;i<=n;i++)if(!dfn[i])Tarjian(i);
        for(int x=1;x<=n;x++){
            for(int i=head[x];i;i=edge[i].nxt){
                int v=edge[i].y;
                if(bel[x]!=bel[v])rd[bel[v]]++;
            }
        }
        for(int i=1;i<=sumclr;i++)if(!rd[i])ans++;
        printf("%d
    ",ans);
        return 0;
    }
    AC
  • 相关阅读:
    iOS8.1 To iOS8.2
    OAuth授权验证说明
    iOS消息推送
    Swift2
    Swift1
    数据结构,每次看都有不一样的体会
    修改CS、IP的指令(学习汇编)
    C,C++中的堆与栈
    12864显示菜单处理编程
    C编程常见的内存错误
  • 原文地址:https://www.cnblogs.com/zzyh/p/7711631.html
Copyright © 2020-2023  润新知