zoukankan      html  css  js  c++  java
  • BZOJ-2140: 稳定婚姻 (tarjan强连通分量)

    2140: 稳定婚姻

    Time Limit: 2 Sec  Memory Limit: 259 MB
    Submit: 952  Solved: 449
    [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

    没记错的话这题laj去年刚学tarjan的时候做过qwq

    然而laj现在已经蒟蒻到tarjan都不会敲了 _(:зゝ∠)_

    此题原配 男向女连一条边,小三 女向男连一条边 如果存在一个环,则环上的各个点都是不安全的♂

    预处理用map很方便qwq

     1 #include "bits/stdc++.h"
     2 using namespace std;
     3 typedef long long LL;
     4 const int MAX=1e4+5;
     5 int n,m;
     6 int tot,head[MAX],adj[MAX<<2],next[MAX<<2];
     7 int dfn[MAX],low[MAX],fro[MAX],sta[MAX],tx,cnt;
     8 bool vis[MAX],ins[MAX];
     9 map <string,int> id;
    10 void addedge(int u,int v){
    11     tot++,adj[tot]=v,next[tot]=head[u],head[u]=tot;
    12 }
    13 void tarjan(int x,int fa){
    14     vis[x]=ins[x]=true;sta[++sta[0]]=x;
    15     dfn[x]=low[x]=++tx;
    16     int i,j;
    17     for (i=head[x];i;i=next[i]){
    18         if (adj[i]==fa) continue;
    19         if (!vis[adj[i]]){
    20             tarjan(adj[i],x);
    21             low[x]=min(low[x],low[adj[i]]);
    22         }
    23         else if (ins[adj[i]]){
    24             low[x]=min(low[x],dfn[adj[i]]);
    25         }
    26     }
    27     if (dfn[x]==low[x]){
    28         ++cnt;
    29         do{
    30             fro[sta[sta[0]]]=cnt;
    31             ins[sta[sta[0]]]=false;
    32         }while (sta[sta[0]--]!=x);
    33     }
    34 }
    35 int main(){
    36     freopen ("marrige.in","r",stdin);freopen ("marrige.out","w",stdout);
    37     int i,j;
    38     char s1[10],s2[10];
    39     scanf("%d
    ",&n);
    40     for (i=1;i<=n;i++){
    41         scanf("%s%s",s1,s2);
    42         id[s1]=i<<1;id[s2]=i<<1|1;
    43         addedge(i<<1,i<<1|1);
    44     }
    45     scanf("%d
    ",&m);
    46     for (i=1;i<=m;i++){
    47         scanf("%s%s",s1,s2);
    48         addedge(id[s2],id[s1]);
    49     }
    50     for (i=1;i<=2*n;i++)
    51         if (!vis[i])
    52             tarjan(i,0);
    53     for (i=1;i<=n;i++)
    54         if (fro[i<<1]!=fro[i<<1|1])
    55             puts("Safe");
    56         else
    57             puts("Unsafe");
    58     return 0;
    59 }
    未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
  • 相关阅读:
    topcoder srm 445 div1
    topcoder srm 440 div1
    topcoder srm 435 div1
    topcoder srm 430 div1
    topcoder srm 400 div1
    topcoder srm 380 div1
    topcoder srm 370 div1
    topcoder srm 425 div1
    WKWebView强大的新特性
    Runtime那些事
  • 原文地址:https://www.cnblogs.com/keximeiruguo/p/7745081.html
Copyright © 2011-2022 走看看