BZOJ 2140: 穩定婚姻

2140: 穩定婚姻

Time Limit: 2 Sec  Memory Limit: 259 MB
Submit: 771  Solved: 359
[Submit][Status][Discuss]

Description

我國的離婚率連續7年上升,今年的頭兩季,平均每天有近5000對夫婦離婚,大城市的離婚率上升最快,有研究婚姻問題的專家認爲,是與簡化離婚手續有關。 25歲的姍姍和男友談戀愛半年就結婚,結婚不到兩個月就離婚,是典型的“閃婚閃離”例子,而離婚的導火線是兩個人爭玩電腦遊戲,丈夫一氣之下,把電腦炸爛。有社會工作者就表示,80後求助個案越來越多,有些是與父母過多幹預有關。而根據民政部的統計,中國離婚五大城市首位是北京,其次是上海、深圳,廣州和廈門,那麼到底是什麼原因導致我國成爲離婚大國呢?有專家分析說,中國經濟急速發展,加上女性越來越來越獨立,另外,近年來簡化離婚手續是其中一大原因。 ——以上內容摘自第一視頻門戶 現代生活給人們施加的壓力越來越大,離婚率的不斷升高已成爲現代社會的一大問題。而其中有許許多多的個案是由婚姻中的“不安定因素”引起的。妻子與丈夫吵架後,心如絞痛,於是尋求前男友的安慰,進而夫妻矛盾激化,最終以離婚收場,類似上述的案例數不勝數。我們已知n對夫妻的婚姻狀況,稱第i對夫妻的男方爲Bi,女方爲Gi。若某男Bi與某女Gj曾經交往過(無論是大學,高中,亦或是幼兒園階段,i≠j),則當某方與其配偶(即Bi與Gi或Bj與Gj)感情出現問題時,他們有私奔的可能性。不妨設Bi和其配偶Gi感情不和,於是Bi和Gj舊情復燃,進而Bj因被戴綠帽而感到不爽,聯繫上了他的初戀情人Gk……一串串的離婚事件像多米諾骨牌一般接踵而至。若在Bi和Gi離婚的前提下,這2n個人最終依然能夠結合成n對情侶,那麼我們稱婚姻i爲不安全的,否則婚姻i就是安全的。給定所需信息,你的任務是判斷每對婚姻是否安全。

Input

第一行爲一個正整數n,表示夫妻的對數;以下n行,每行包含兩個字符串,表示這n對夫妻的姓名(先女後男),由一個空格隔開;第n+2行包含一個正整數m,表示曾經相互喜歡過的情侶對數;以下m行,每行包含兩個字符串,表示這m對相互喜歡過的情侶姓名(先女後男),由一個空格隔開。

Output

輸出文件共包含n行,第i行爲“Safe”(如果婚姻i是安全的)或“Unsafe”(如果婚姻i是不安全的)。

Sample Input

【樣例輸入1】
2
Melanie Ashley
Scarlett Charles
1
Scarlett Ashley

【樣例輸入2】
2
Melanie Ashley
Scarlett Charles
2
Scarlett Ashley
Melanie Charles

Sample Output

【樣例輸出1】
Safe
Safe

【樣例輸出2】
Unsafe
Unsafe
【數據規模和約定】
對於100%的數據,所有姓名字符串中只包含英文大小寫字母,大小寫敏感,長度不大於8,保證每對關係只在輸入文件中出現一次,輸入文件的最後m行不會出現未在之前出現過的姓名,這2n個人的姓名各不相同,1≤n≤4000,0≤m≤20000。

HINT

Source

[Submit][Status][Discuss]
題解:還以爲是二分圖匹配還是那個奧妙重重的數學問題QAQ 結果是強聯通分量?!!!
初始時由女向男連一條邊,情人由男向女連一條邊,然後tarjan一波,如果夫妻兩人在同一個連通分量中,那完了GG。
貼上代碼:
#include<bits/stdc++.h>
#define MAXN 10005
using namespace std;
int n,m,head[MAXN],cnt=0,dfn[MAXN],low[MAXN],dfn_clock=0,tot=0,sccno[MAXN];
bool vis[MAXN],ins[MAXN];
map<string,int>id;
stack<int>s;
struct Node
{
    int next,to;
}Edges[MAXN*4];
void addedge(int u,int v)
{
    Edges[++cnt].next=head[u];
    head[u]=cnt;
    Edges[cnt].to=v;
}
void tarjan(int u)
{
    dfn[u]=low[u]=++dfn_clock;
    vis[u]=ins[u]=1;s.push(u);
    for(int i=head[u];~i;i=Edges[i].next)
    {
        int v=Edges[i].to;
        if(!vis[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(ins[v])
        {low[u]=min(low[u],dfn[v]);}
    }
    if(dfn[u]==low[u])
    {
        tot++;int t=-1;
        while(t!=u)
        {
            t=s.top();
            sccno[t]=tot;
            ins[t]=0;
            s.pop();
        }
    }
}
int main()
{
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    char female[10],male[10];
    for(int i=0;i<n;i++)
    {
        scanf("%s%s",female,male);
        id[female]=2*i;
        id[male]=2*i+1;
        addedge(2*i,2*i+1);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%s%s",female,male);
        addedge(id[male],id[female]);
    }
    for(int i=0;i<2*n;i++)if(!vis[i])tarjan(i);
    for(int i=0;i<n;i++)
    {
        if(sccno[2*i]==sccno[2*i+1])printf("Unsafe\n");
        else printf("Safe\n");
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章