• AC日记——传话 codevs 1506 (tarjan求环)


    1506 传话

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 白银 Silver
     
     
     
    题目描述 Description

    一个朋友网络,如果a认识b,那么如果a第一次收到某个消息,那么会把这个消息传给b,以及所有a认识的人。

    如果a认识b,b不一定认识a。

    所有人从1到n编号,给出所有“认识”关系,问如果i发布一条新消息,那么会不会经过若干次传话后,这个消息传回给了i,1<=i<=n。

    输入描述 Input Description

    第一行是n和m,表示人数和认识关系数。

    接下来的m行,每行两个数a和b,表示a认识b。1<=a, b<=n。认识关系可能会重复给出,但一行的两个数不会相同。

    输出描述 Output Description

    一共n行,每行一个字符T或F。第i行如果是T,表示i发出一条新消息会传回给i;如果是F,表示i发出一条新消息不会传回给i。

     

    样例输入 Sample Input

    4 6

    1 2

    2 3

    4 1

    3 1

    1 3

    2 3

    样例输出 Sample Output

    T

    T

    T

    F

    数据范围及提示 Data Size & Hint

    n<=1000

    1<=a, b<=n

    分类标签 Tags 点此展开 

     
     
     
    思路:
      判断每个人的话能不能传回自己
      用搜索就很容易ac
      但是今天的主要练习是tarjan
      (Q:tarjan是什么?)
      (A:不会面壁去,不懂百度去)
      用tarjan求出所有的环
      然后把每个点就标记一下
      每个标记指向这个点所属的环
      如果这个点所指向的环的元素个数大于1(成环能回到自己)则输出T
      否则(环的元素个数为1,只有他自己)输出F
     
     
     
      来,上代码:
    #include<cstdio>
    #include<iostream>
    
    using namespace std;
    
    struct node {
        int from,to,next;
    };
    struct node edge[1000001];
    
    int n,m,num=0,head[1001],dfn[1001],low[1001];
    int tarjan_dfn=0,tarjan_loop=0,loop[1001];
    int stack[1001],stack_top=0,belong[1001];
    
    bool map[1001][1001],flag[1001];
    
    char ch;
    
    inline void edge_add(int from,int to)
    {
        num++;
        edge[num].to=to;
        edge[num].from=from;
        edge[num].next=head[from];
        head[from]=num;
    }
    
    inline void qread(int &x)
    {
        x=0;ch=getchar();
        while(ch>'9'||ch<'0') ch=getchar();
        while(ch<='9'&&ch>='0'){x=x*10+(int)(ch-'0');ch=getchar();}
    }
    
    void tarjan_forloop(int serc)
    {
        tarjan_dfn++;
        dfn[serc]=tarjan_dfn;
        low[serc]=tarjan_dfn;
        stack_top++;
        stack[stack_top]=serc;
        flag[serc]=true;
        for(int i=head[serc];i!=0;i=edge[i].next)
        {
            if(!dfn[edge[i].to])
            {
                tarjan_forloop(edge[i].to);
                low[serc]=min(low[serc],low[edge[i].to]);
            }
            else if(flag[edge[i].to]) low[serc]=min(low[serc],low[edge[i].to]);
        }
        if(low[serc]==dfn[serc])
        {
            tarjan_loop++;
            while(stack[stack_top]!=serc)
            {
                loop[tarjan_loop]++;
                belong[stack[stack_top]]=tarjan_loop;
                flag[stack[stack_top]]=false;
                stack_top--;
            }
            loop[tarjan_loop]++;
            belong[stack[stack_top]]=tarjan_loop;
            flag[stack[stack_top]]=false;
            stack_top--;
        }
    }
    
    int main()
    {
        int from,to;
        qread(n),qread(m);
        for(int i=1;i<=m;i++)
        {
            qread(from),qread(to);
            if(map[from][to]) continue;
            map[from][to]=true;
            edge_add(from,to);
        }
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjan_forloop(i);
        for(int i=1;i<=n;i++)
        {
            if(loop[belong[i]]>1)
            {
                putchar('T');
                putchar('
    ');
            }
            else
            {
                putchar('F');
                putchar('
    ');
            }
        }
        return 0;
    }
  • 相关阅读:
    判断数据库内容,在页面显示自定义数据case when
    其他窗体赋值给comboBox实现值的回显,并使赋的值处于选中状态(根据text获取selectedindex)
    DataGridView的按钮列的点击事件
    表单中各种input汇总
    块元素、内敛元素、行内块元素特点、相互转换、取消默认效果
    内联元素,取消间隙和默认效果
    margin-top塌陷
    linux下安装 配置 redis数据库
    redis数据库各种数据类型的增删改查命令
    python与mongodb的交互 增删改差
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6051036.html
Copyright © 2020-2023  润新知