zoukankan      html  css  js  c++  java
  • luogu P2002 消息扩散

    题目背景

    本场比赛第一题,给个简单的吧,这 100 分先拿着。

    题目描述

    有n个城市,中间有单向道路连接,消息会沿着道路扩散,现在给出n个城市及其之间的道路,问至少需要在几个城市发布消息才能让这所有n个城市都得到消息。

    输入输出格式

    输入格式:

    第一行两个整数n,m表示n个城市,m条单向道路。

    以下m行,每行两个整数b,e表示有一条从b到e的道路,道路可以重复或存在自环。

    输出格式:

    一行一个整数,表示至少要在几个城市中发布消息。

    输入输出样例

    输入样例#1:
    5 4
    1 2
    2 1
    2 3
    5 1
    
    输出样例#1:
    2
    

    说明

    【数据范围】

    对于20%的数据,n≤200;

    对于40%的数据,n≤2,000;

    对于100%的数据,n≤100,000,m≤500,000.

    【限制】

    时间限制:1s,内存限制:256M

    【注释】

    样例中在4,5号城市中发布消息。

     tarjan算法将每个强连通分量缩成点,记录原先的每个点缩入了哪个点

    缩完之后,扫描每条边,判断如果终点和起点所在的分量不同,标记终点

    最后扫描为标记的的点计数器++也就是(入度为0的点)

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    int n,m,topp;
    #define N 100006
    struct sta{
        int sz[100001];
        int top(){return sz[topp];}
        void push(int x){sz[++topp]=x;}
        void pop(){if(topp>0)topp--;}
    }stack;
    
    struct node{
        int v,next;
    }edge[N*5];int head[N],num;
    int dfn[N],low[N],color[N];bool vis[N];
    
    void add_edge(int x,int y)
    {
        edge[++num].v=y;edge[num].next=head[x];head[x]=num;
    }
    int cnt;
    void tarjan(int x)
    {
        dfn[x]=low[x]=++num;
        stack.push(x);
        vis[x]=1;
        for(int i=head[x];i;i=edge[i].next)
        {
            int v=edge[i].v;
            if(!dfn[v])
            {
                tarjan(v);
                low[x]=min(low[x],low[v]);
            }
            else if(vis[v])low[x]=min(low[x],dfn[v]);    
        }
        if(dfn[x]==low[x])
        {
            ++cnt;
            int r;
            do{
                r=stack.top();
                color[r]=cnt;
                vis[r]=0;
                stack.pop();
            }while(r!=x);
        }
        return ;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        int a,b;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);add_edge(a,b);
        }
        num=0;
        for(int i=1;i<=n;i++)
        if(!dfn[i])tarjan(i);
        memset(vis,0,sizeof vis);
        for(int i=1;i<=n;i++)
        {
            for(int j=head[i];j;j=edge[j].next)
            {
                int v=edge[j].v;
                if(color[i]!=color[v])
                {
                    vis[color[v]]=1;
                }
            }
        }
        int ans=0;
        for(int i=1;i<=cnt;i++)
            if(!vis[i]) ans++;
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    java操作生成jar包 和写入jar包
    jboss配置jndi连接池
    windows 域的LDAP查询相关举例
    LDAP error Code 及解决方法
    HDU 6417
    CF1299D Around the World
    codechef Chef and The Colored Grid
    Educational Codeforces Round 82 (Rated for Div. 2)
    CF1237F Balanced Domino Placements
    CF1254E Send Tree to Charlie
  • 原文地址:https://www.cnblogs.com/sssy/p/7074426.html
Copyright © 2011-2022 走看看