codevs2822爱在心中

小时のblog 小时のblog     2022-08-31     653

关键词:

 传送门:http://codevs.cn/problem/2822/
时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
题目描述 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

【解析】

hehe

2822 爱在心中 100 8ms 2 MB C++ 1352B 2017/05/11 17:24:19
2822 爱在心中 30 28ms 2 MB C++ 1345B 2017/05/11 17:22:13
2822 爱在心中 70 160ms 18 MB C++ 1970B 2017/05/11 16:54:26
2822 爱在心中 70 3ms 1 MB C++ 1969B 2017/05/11 16:50:27
2822 爱在心中 40 3ms 1 MB C++ 1951B 2017/05/11 16:47:24
2822 爱在心中 30 3ms 1 MB C++ 2064B 2017/05/11 16:38:19
2822 爱在心中 10 4ms 1 MB C++ 2278B 2017/05/11 16:22:16
2822 爱在心中 30 5ms 1 MB C++ 2038B 2017/05/11 15:58:50
2822 爱在心中 10 4ms 1 MB C++ 1966B 2017/05/11 15:56:32
2822 爱在心中 10 6ms 1 MB C++ 1966B 2017/05/11 15:40:40
2822 爱在心中 0 5ms 1 MB C++ 1936B 2017/05/11 15:20:44
2822 爱在心中 0 19ms 1 MB C++ 2074B 2017/05/11 15:18:46

 

强连通分量+tarjan+缩点。

彼此相爱的人就是一个强连通分量,让这些彼此相爱的人抱在一起成为一个小天使。也就是缩点。最后缩成几个点就是有几个小天使。

因为如果所有小天使都喜欢那个小天使的话,那个小天使的出度一定是0,并且只有一个出度为0的点,注意图可能不连通。

注意一个点构成的强连通分量不是一个小天使(QWQ),然后就一直WA这个样例。

 

1爱着2,可是2没有爱1。因为是单相思所以没有小天使。

k!我现在才想起来题目中说的不能自爱原来是没有单个点的意思。。。。。

【code】

借鉴了一下dalao的。

#include<iostream>
#include<cstdio>
using namespace std;
#define N 202020
struct Edge
{
    int x,y,next;
    Edge(int x=0,int y=0,int next=0):
        x(x),y(y),next(next){}
}edge[N];
int sumedge,tim,an,js,top,sumclr,ann,n,m;
int head[N],low[N],dfn[N],Stack[N],cnt[N],color[N],cd[N],x[N],y[N];
bool instack[N];
int ins(int x,int y)
{
    edge[++sumedge]=Edge(x,y,head[x]);
    return head[x]=sumedge;
}
void tarjan(int x)
{
    Stack[++top]=x;instack[x]=1;
    low[x]=dfn[x]=++tim;
    for(int u=head[x];u;u=edge[u].next)
    if(instack[edge[u].y])
    low[x]=min(low[x],dfn[edge[u].y]);
    else
    if(!dfn[edge[u].y])
    {
        tarjan(edge[u].y);
        low[x]=min(low[x],low[edge[u].y]);
    }
    else
    {}
    if(low[x]==dfn[x])
    {
        sumclr++;
        while(Stack[top+1]!=x)//top+1保证x出去。 
        {
            color[Stack[top]]=sumclr;
            instack[Stack[top]]=false;
            cnt[sumclr]++;
            top--;
        }
    }
}
int main() 
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
    scanf("%d %d",&x[i],&y[i]);    
    ins(x[i],y[i]);
    }
    for(int i=1;i<=n;i++)
    if(!dfn[i])tarjan(i);//注意图可能b不连通。 
    for(int i=1;i<=m;i++)
    if(color[x[i]]!=color[y[i]])cd[color[x[i]]]++;//相当于缩点吧...统计出度。 
    for(int i=1;i<=sumclr;i++)if(!cd[i])an=i,js++;
    for(int i=1;i<=sumclr;i++)if(cnt[i]>1)ann++;//不能自爱。(好奇怪的样子) 
    printf("%d\n",ann);
    if(js==1&&cnt[an]>1)
    {
        for(int i=1;i<=n;i++)
        if(color[i]==an)
        printf("%d ",i);
    }
    else
    puts("-1");
    return 0;    
}

【我的调了2个小时才调到70分而且又丑又遭嫌弃的code】

//恨在心中 
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
#define N 202020
struct Edge
{
    int x,y,next;
    Edge(int x=0,int y=0,int next=0):
        x(x),y(y),next(next){}
}edge[N<<1];
int sumedge,sumedge2,x,y,n,m,tim,top,sumclr,js,ans;
int head[N],head2[N],low[N],dfn[N],color[N],Stack[N],out[N],tmp[N],cnt[N];
bool instack[N],vis[N],can[N];
map<int,bool>Map[N];
vector<int>vec[N];
int ins(int x,int y)
{
    edge[++sumedge]=Edge(x,y,head[x]);
    return head[x]=sumedge;
}
int ins2(int x,int y)
{
    edge[++sumedge2]=Edge(x,y,head2[x]);
    return head2[x]=sumedge2;
}
void dfs(int x)
{
    vis[x]=1;
    low[x]=dfn[x]=++tim;
    instack[x]=1;Stack[++top]=x;
    for(int u=head[x];u;u=edge[u].next)
    if(instack[edge[u].y])
    low[x]=min(low[x],dfn[edge[u].y]);
    else
    if(!vis[edge[u].y])
    {
        dfs(edge[u].y);
        low[x]=min(low[x],low[edge[u].y]);
    }
    else
    {
    }
    if(low[x]==dfn[x])
    {
        sumclr++;color[x]=sumclr;
        vec[sumclr].push_back(x); 
        cnt[sumclr]++;
        while(Stack[top]!=x)
        {
            color[Stack[top]]=sumclr;
            instack[Stack[top]]=false;
            vec[sumclr].push_back(Stack[top]);
            top--;
            cnt[sumclr]++;
        }
        instack[x]=false;
        top--;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        ins(x,y);
    }
    for(int i=1;i<=n;i++)
    {
        if(!vis[i])
        dfs(i);
    }
    int an=0;
    for(int i=1;i<=sumclr;i++)
    if(cnt[i]>1)an++;
     printf("%d\n",an);
    for(int i=1;i<=n;i++)
        for(int u=head[i];u;u=edge[u].next)
            if(color[i]!=color[edge[u].y])
            if(Map[color[i]].find(color[edge[u].y])==Map[color[i]].end())
            {
                Map[color[i]][color[edge[u].y]]=true;
                ins2(color[i],color[edge[u].y]);
                out[color[i]]++;
            }
    for(int i=1;i<=sumclr;i++)
    {
        if(out[i]==0)
        {
            js++;
            ans=i;
        }
    }
    if(js==1&&cnt[ans]>1)
    {
    for(int i=1;i<=n;i++)
    if(color[i]==ans)printf("%d ",i);
    }
    else
    puts("-1");
    return 0;
}

 

codevs2822爱在心中

...不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢OurHome。”在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自... 查看详情

codevs2822爱在心中tarjan(强联通分量)

2822爱在心中  时间限制:1s 空间限制:128000KB 题目等级:钻石Diamond  题目描述 Description“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,... 查看详情

[codevs2822]爱在心中

思路:Tarjan+缩点。首先跑一遍Tarjan,统计结点个数大于$1$的连通分量个数。然后寻找统计结点个数大于$1$且出度为$0$的连通分量,若只存在一个这样的连通分量,输出其点集即可。1#include<stack>2#include<cstdio>3#include<ccty... 查看详情

强连通分量——爱在心中(codevs_2822)——tarjan求scc

scc找只有一个节点的强连通分量,标记。第一行输出强连通分量个数(不为1个节点)缩点建图找出度为0的点。超过一个或者该点被标记,puts(“-1”);else输出答案。#include<iostream>#include<cstdio>#include<vector>#include&l... 查看详情

codves2822爱在心中

            2822爱在心中 时间限制:1s   空间限制:128000KB 题目描述 Description“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,... 查看详情

[codevs2882]爱在心中(代码片段)

...不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢OurHome。”在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自... 查看详情

tarjan笔记1

Tarjan2822爱在心中**时间限制:1s**空间限制:128000KB**题目等级:钻石Diamond题解题目描述Description“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又... 查看详情

爱在心中

爱在心中 vijos-1626jdoj-1588    题目大意:给你n个点和m条有向边,求出大于一的强连通分量的个数以及是否存在唯一的强连通分量使得这个分量可以被任意点到达。如果存在,则排序输出这个强联通分量里的点,如果不存... 查看详情

vijos——t1626爱在心中

...不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢OurHome。”在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自... 查看详情

codevs2822

解题思路:tarjan缩点后算出度为0的点有几个,如果只有一个且这个点为爱心天使就行了;#include<iostream>#include<algorithm>#include<vector>#include<queue>#include<cstdio>#include<cstring>#definemaxn10005usi 查看详情

codevs3165爱改名的小融2

3149爱改名的小融2http://codevs.cn/problem/3149/题目描述 DescriptionWikioi上有个人叫小融,他喜欢改名。现在他的要求变了,只要是英文字母就是他的名字。先给你N个名字,请你一一判断是不是小融。本题还加强了测试数据 输入... 查看详情

ac日记——爱改名的小融codevs2967

2967爱改名的小融  时间限制:1s 空间限制:16000KB 题目等级:白银Silver题解   题目描述 DescriptionWikioi上有个人叫小融,他喜欢改名。他的名字都是英文,只要按顺序出现R,K,Y三个字母,就是他的名字。给... 查看详情

ac日记——爱改名的小融3codevs3156

3156爱改名的小融3  时间限制:1s 空间限制:128000KB 题目等级:黄金Gold题解   题目描述 DescriptionWikioi上有个人叫小融,他喜欢改名。现在他的要求变了,只要是英文字母就是他的名字。先给你N个名字,... 查看详情

ac日记——爱改名的小融2codevs3149

3149爱改名的小融2  时间限制:2s 空间限制:128000KB 题目等级:黄金Gold题解   题目描述 DescriptionWikioi上有个人叫小融,他喜欢改名。现在他的要求变了,只要是英文字母就是他的名字。先给你N个名字,... 查看详情

受欢迎的牛

...想法:这题也是一道tarjan裸题,让我来A掉吧!这题和爱在心中(爱在心中?猛戳)类似,只不过这题有坑......用panxf的模板A不掉这道题......为什么呢?因为n的数据范围,会MLE。但是我们发现,这道 查看详情

codevs3411洪水

题目描述 Description小浣熊松松和朋友到野外露营,没想到遇上了&pi;年一次的大洪水,好在松松是一只爱观察的小浣熊,他发现露营地的地形和洪水有如下性质:①露营地可以被看做是一个N*M的矩形方阵,其中左上角坐标... 查看详情

codevs2277爱吃皮蛋的小明

时间限制:1s 空间限制:32000KB 题目等级:白银Silver题目描述 Description小明特别爱吃蛋,特别是皮蛋。他一次可以吃一个蛋或者两个蛋(整个吞下去),而且他喜欢吃得有花样,他想知道对于一定蛋的数量,有几种不同的... 查看详情

在 JAVA 中解析 RFC 2822 日期

】在JAVA中解析RFC2822日期【英文标题】:ParsingRFC2822dateinJAVA【发布时间】:2011-01-2808:21:20【问题描述】:我需要在Java中解析日期的RFC2822字符串表示。示例字符串在这里:2010年3月13日星期六11:29:05-0800它看起来很糟糕,所以我想确... 查看详情