zoukankan      html  css  js  c++  java
  • codves 2822 爱在心中 && bzoj 1051: [HAOI2006]受欢迎的牛

                2822 爱在心中
     时间限制: 1 s     空间限制: 128000 KB
     
    题目描述 Description

    “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home。”

    在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况)。爱是具有传递性的,即如果A爱B,B爱C,则A也爱C。
    如果有这样一部分人,他们彼此都相爱,则他们就超越了一切的限制,用集体的爱化身成为一个爱心天使。
    现在,我们想知道在这个爱的国度里会出现多少爱心天使。而且,如果某个爱心天使被其他所有人或爱心天使所爱则请输出这个爱心天使是由哪些人构成的,否则输出-1。

    输入描述 Input Description

    第1行,两个数N、M,代表爱的国度里有N个人,爱的关系有M条。
    第2到第M+1行,每行两个数A、B,代表A爱B。

    输出描述 Output Description

    第1行,一个数,代表爱的国度里有多少爱心天使。
    第2行,如果某个爱心天使被其他所有人和爱心天使所爱则请输出这个爱心天使是由哪些人构成的(从小到大排序),否则输出-1。

    样例输入 Sample Input

    样例输入1:

    6 7
    1 2
    2 3
    3 2
    4 2
    4 5
    5 6
    6 4


    样例输入2:

    3 3
    1 2
    2 1
    2 3

    样例输出 Sample Output

    样例输出1:

    2
    2 3

    样例输出2:

    1
    -1

    数据范围及提示 Data Size & Hint

    各个测试点1s

    解:强联通分量;

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using std::min;
    const int N=100010; 
    struct node{int next,to,from;}e[N];
    int first[N];
    int book[N];
    int dfn[N],low[N],stack[N],cd[N];
    int cnt=0;
    void insert(int v,int u)
    {
        e[++cnt].to=u;e[cnt].from=v;e[cnt].next=first[v];first[v]=cnt;
    }
    int tot=0,top=0,num=0;
    int size[N],color[N];
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tot;
        book[x]=1;stack[++top]=x;
        for(int i=first[x];i;i=e[i].next)
        {
            if(!dfn[e[i].to]) tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);
            else if(book[e[i].to])    low[x]=min(low[x],low[e[i].to]);
        }
        if(dfn[x]==low[x])
        {
            ++num;
            while(stack[top]!=x)
            {
                book[stack[top]]=0;
                color[stack[top]]=num;
                size[num]++;
                top--;
            }
            book[x]=0;
            color[x]=num;
            size[num]++;
            top--;
        }
    }
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        int v,u;
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d",&v,&u);
            insert(v,u);
        }
        int ans=0;
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
        for(int i=1;i<=num;i++) if(size[i]!=1) ans++;
        printf("%d
    ",ans);
        cnt=0;
        memset(first,0,sizeof(first));
        for(int i=1;i<=m;i++) 
        if(color[e[i].from]!=color[e[i].to]) cd[color[e[i].from]]++,insert(color[e[i].from],color[e[i].to]);
        ans=0;
        int aim=0;
        for(int i=1;i<=num;i++) if(!cd[i]) ans++,aim=i;
        if(ans!=1) printf("-1");
        else 
        {
            if(size[aim]==1) printf("-1");
            else for(int i=1;i<=n;i++) if(color[i]==aim) printf("%d ",i);
        }
        return 0;
    }
    codves 2822

    --------------

    1051: [HAOI2006]受欢迎的牛

    Time Limit: 10 Sec  Memory Limit: 162 MB

    Description

      每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
    种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
    牛被所有的牛认为是受欢迎的。

    Input

      第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可
    能出现多个A,B)

    Output

      一个数,即有多少头牛被所有的牛认为是受欢迎的。

    Sample Input

    3 3
    1 2
    2 1
    2 3

    Sample Output

    1

    HINT

    100%的数据N<=10000,M<=50000
    解:同上;
    强联通分量大多要in,cd;
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using std::min;
    const int N=100010; 
    struct node{int next,to,from;}e[N];
    int first[N];
    int book[N];
    int dfn[N],low[N],stack[N],cd[N];
    int cnt=0;
    void insert(int v,int u)
    {
        e[++cnt].to=u;e[cnt].from=v;e[cnt].next=first[v];first[v]=cnt;
    }
    int tot=0,top=0,num=0;
    int size[N],color[N];
    void tarjan(int x)
    {
        dfn[x]=low[x]=++tot;
        book[x]=1;stack[++top]=x;
        for(int i=first[x];i;i=e[i].next)
        {
            if(!dfn[e[i].to]) tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);
            else if(book[e[i].to])    low[x]=min(low[x],low[e[i].to]);
        }
        if(dfn[x]==low[x])
        {
            ++num;
            while(stack[top]!=x)
            {
                book[stack[top]]=0;
                color[stack[top]]=num;
                size[num]++;
                top--;
            }
            book[x]=0;
            color[x]=num;
            size[num]++;
            top--;
        }
    }
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        int v,u;
        for(int i=1;i<=m;i++)
        {
            scanf("%d %d",&v,&u);
            insert(v,u);
        }
        int ans=0;
        for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
        for(int i=1;i<=num;i++) if(size[i]!=1) ans++;    
        cnt=0;
        memset(first,0,sizeof(first));
        for(int i=1;i<=m;i++) 
        if(color[e[i].from]!=color[e[i].to]) cd[color[e[i].from]]++,insert(color[e[i].from],color[e[i].to]);
        ans=0;
        int aim;
        for(int i=1;i<=num;i++) if(!cd[i]) ans++,aim=i;
        if(ans!=1) printf("0");
        else printf("%d
    ",size[aim]);
        return 0;
    }
    bzoj 1051

    ----------

  • 相关阅读:
    Java反射得到属性的值和设置属性的值
    想建一个比较严格的自律打卡监督群,群主真的会很较真
    JS面向对象篇四、原型链与继承(多种继承实现方式及其利弊分析)
    JS面向对象篇三、创建对象的几种方法
    JS面向对象篇二、什么是原型?原型对象与实例对象、构造函数的关系及相关方法
    JS面向对象篇一、理解对象及属性特性(属性描述符)
    javascript作用域篇一、什么是javascript作用域链
    javascript函数篇四、函数的属性和方法——apply()、call()和bind()方法区别
    javascript函数篇三、函数声明提升
    javascript函数篇二、深入理解为什么javascript中没有函数重载
  • 原文地址:https://www.cnblogs.com/12fs/p/7650252.html
Copyright © 2011-2022 走看看