1. 程式人生 > >codevs 2822 愛在心中

codevs 2822 愛在心中

pre sta tdi pac color too default 個人 pri

傳送門: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;
}

codevs 2822 愛在心中