codevs2822爱在心中
Posted chty
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs2822爱在心中相关的知识,希望对你有一定的参考价值。
题目描述 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
【题解】
第一问的答案就是缩点后长度大于1的环的数量。
第二问:注意到一点:缩点后满足条件的点一定是出度为0,那么就好办了,遍历每个点,如果出度为零,记录下来,然后去找。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<ctime> 6 #include<cmath> 7 #include<algorithm> 8 using namespace std; 9 #define MAXN 50010 10 struct node{int y,next;}e[MAXN],e2[MAXN]; 11 int n,m,now,len,top,bcnt,Link[MAXN],Link2[MAXN],dfn[MAXN],low[MAXN],instack[MAXN],stack[MAXN],belong[MAXN],size[MAXN]; 12 inline int read() 13 { 14 int x=0,f=1; char ch=getchar(); 15 while(!isdigit(ch)) {if(ch==‘-‘) f=-1; ch=getchar();} 16 while(isdigit(ch)) {x=x*10+ch-‘0‘; ch=getchar();} 17 return x*f; 18 } 19 void insert(int x,int y) {e[++len].next=Link[x];Link[x]=len;e[len].y=y;} 20 void Insert(int x,int y) {e2[++len].next=Link2[x];Link2[x]=len;e2[len].y=y;} 21 void tarjan(int x) 22 { 23 dfn[x]=low[x]=++now; 24 instack[x]=1; stack[++top]=x; 25 for(int i=Link[x];i;i=e[i].next) 26 { 27 if(!dfn[e[i].y]) 28 { 29 tarjan(e[i].y); 30 low[x]=min(low[x],low[e[i].y]); 31 } 32 else if(instack[e[i].y]) low[x]=min(low[x],dfn[e[i].y]); 33 } 34 if(low[x]==dfn[x]) 35 { 36 int y; bcnt++; 37 do 38 { 39 y=stack[top--]; 40 instack[y]=0; 41 belong[y]=bcnt; 42 size[bcnt]++; 43 }while(x!=y); 44 } 45 } 46 int main() 47 { 48 //freopen("cin.in","r",stdin); 49 //freopen("cout.out","w",stdout); 50 n=read(); m=read(); 51 for(int i=1;i<=m;i++) 52 { 53 int x=read(),y=read(); 54 insert(x,y); 55 } 56 len=0; 57 for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); 58 for(int i=1;i<=n;i++) 59 for(int j=Link[i];j;j=e[j].next) 60 if(belong[e[j].y]!=belong[i]) 61 Insert(belong[i],belong[e[j].y]); 62 int ans=0; 63 for(int i=1;i<=bcnt;i++) 64 if(size[i]>1) ans++; 65 printf("%d\n",ans); 66 ans=-1; 67 for(int i=1;i<=bcnt;i++) 68 if(!Link2[i]) 69 { 70 if(ans!=-1||size[i]==1) {ans=-1; break;} 71 else ans=i; 72 } 73 if(ans==-1) {printf("-1\n"); return 0;} 74 for(int i=1;i<=n;i++) 75 if(belong[i]==ans) printf("%d ",i); 76 printf("\n"); 77 return 0; 78 }
以上是关于codevs2822爱在心中的主要内容,如果未能解决你的问题,请参考以下文章
codevs 2822 爱在心中 tarjan(强联通分量)