您的位置:首页 > 其它

[CodeVS2822]爱在心中 做题笔记

2016-02-28 11:24 344 查看
题目来源 :http://codevs.cn/problem/2822/

题目描述 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 <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int N=50005;
struct ljb {
int to,next;
}e
,d
;
int head
;
bool vis
,inq
;
int q
,low
,dfn
,success=1;
int n,m,top=0,cnt=0,scc=0,belong
,hav
,h
;
int sum=0;
int ans
,o=0;
void DFS (int a) {
int now;
vis[a]=inq[a]=1;
top++,cnt++;
q[top]=a;
low[a]=dfn[a]=cnt;
for (int i=head[a];i;i=e[i].next) {
if (!vis[e[i].to]) {
DFS(e[i].to);
low[a]=min(low[a],low[e[i].to]);
}
else if (inq[e[i].to]) {
low[a]=min(low[a],dfn[e[i].to]);
}
}
if (dfn[a]==low[a]) {
scc++;
while (now!=a) {
now=q[top--];
inq[now]=0;
belong[now]=scc;
hav[scc]++;
}
}
}
void Shrink () {
cnt=0;
for (int i=1;i<=n;i++) {
for (int j=head[i];j;j=e[j].next) {
if (belong[i]!=belong[e[j].to]) {
cnt++;
d[cnt].to=belong[e[j].to];
d[cnt].next=h[belong[i]];
h[belong[i]]=cnt;
}
}
}
}
void Tarjan () {
for (int i=1;i<=n;i++) {
if (!vis[i]) DFS(i);
}
Shrink();
}
void Findans () {
for (int i=1;i<=scc;i++) {
if (hav[i]>1) sum++;
if (!h[i]) {
if (o) success=0;
o=i;
}
}
}
bool rule (int x,int y) {
return x<y;
}
int main () {
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++) {
int x,y;
scanf("%d%d",&x,&y);
e[i].to=y;
e[i].next=head[x];
head[x]=i;
}
Tarjan();
Findans();
printf("%d\n",sum);
if (!success) {
printf("-1");
return 0;
}
else {
if (hav[o]==1) {
printf("-1");
return 0;
}
else {
cnt=0;
for (int i=1;i<=n;i++)
if (belong[i]==o) ans[++cnt]=i;
sort(ans+1,ans+1+cnt,rule);
for (int i=1;i<=cnt;i++) printf("%d ",ans[i]);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: