codevs 2822 爱在心中
Posted 小时のblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 2822 爱在心中相关的知识,希望对你有一定的参考价值。
“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动。爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home。”
在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况)。爱是具有传递性的,即如果A爱B,B爱C,则A也爱C。
如果有这样一部分人,他们彼此都相爱,则他们就超越了一切的限制,用集体的爱化身成为一个爱心天使。
现在,我们想知道在这个爱的国度里会出现多少爱心天使。而且,如果某个爱心天使被其他所有人或爱心天使所爱则请输出这个爱心天使是由哪些人构成的,否则输出-1。
第1行,两个数N、M,代表爱的国度里有N个人,爱的关系有M条。
第2到第M+1行,每行两个数A、B,代表A爱B。
第1行,一个数,代表爱的国度里有多少爱心天使。
第2行,如果某个爱心天使被其他所有人和爱心天使所爱则请输出这个爱心天使是由哪些人构成的(从小到大排序),否则输出-1。
样例输入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
样例输出1:
2
2 3
样例输出2:
1
-1
各个测试点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; }
以上是关于codevs 2822 爱在心中的主要内容,如果未能解决你的问题,请参考以下文章
codevs 2822 爱在心中 tarjan(强联通分量)