题目描述:
现代生活给人们施加的压力越来越大,离婚率的不断升高已成为现代社会的一大问题。而其中有许许多多的个案是由婚姻中的“不安定因素”引起的。妻子与丈夫吵架后,心如绞痛,于是寻求前男友的安慰,进而夫妻矛盾激化,最终以离婚收场,类似上述的案例数不胜数。
我们已知n对夫妻的婚姻状况,称第i对夫妻的男方为Bi,女方为Gi。若某男Bi与某女Gj曾经交往过(无论是大学,高中,亦或是幼儿园阶段,i≠j),则当某方与其配偶(即Bi与Gi或Bj与Gj)感情出现问题时,他们有私奔的可能性。不妨设Bi和其配偶Gi感情不和,于是Bi和Gj旧情复燃,进而Bj因被戴绿帽而感到不爽,联系上了他的初恋情人Gk……一串串的离婚事件像多米诺骨牌一般接踵而至。若在Bi和Gi离婚的前提下,这2n个人最终依然能够结合成n对情侣,那么我们称婚姻i为不安全的,否则婚姻i就是安全的。
给定所需信息,你的任务是判断每对婚姻是否安全。
输入格式
第一行为一个正整数n,表示夫妻的对数;
以下n行,每行包含两个字符串,表示这n对夫妻的姓名(先女后男),由一个空格隔开;
第n+2行包含一个正整数m,表示曾经相互喜欢过的情侣对数;
以下m行,每行包含两个字符串,表示这m对相互喜欢过的情侣姓名(先女后男),由一个空格隔开。
输出格式
输出文件共包含n行,第i行为“Safe”(如果婚姻i是安全的)或“Unsafe”(如果婚姻i是不安全的)。
题解:
首先输入夫妻的时候,用左边的女性连向右边的男性建边,当然不能用字符串,我们得先map存一下,然后在输入情人关系时,将右边的男性和左边的女性建边,容易发现,如果图中有环一定包含了多对夫妻,那么他们就是不安全的,也就是缩点以后在同一联通块中
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
#define LL long long
const int MAXN = 1e5+50;
const int MAXM = 2e5+50;
const int MOD = 1e9+7;
const double PI = acos(-1);
inline char getc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
int x=0,f=1; char ch=getc();
while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getc(); }
while(isdigit(ch)) x=x*10+ch-48,ch=getc();
return x*f;
}
int n,m,tot,cnt,k,top,head[MAXN],to[MAXM],nxt[MAXM];
int dfn[MAXN],low[MAXN],instack[MAXN],st[MAXN],bel[MAXN];
inline void add(int u,int v){
to[++tot]=v; nxt[tot]=head[u]; head[u]=tot;
}
void tarjan(int u){
dfn[u]=low[u]=++cnt; st[++top]=u; instack[u]=1;
for(int i=head[u];i;i=nxt[i]){
if(!dfn[to[i]]) tarjan(to[i]),low[u]=min(low[u],low[to[i]]);
else if(instack[to[i]]) low[u]=min(low[u],dfn[to[i]]);
}
if(dfn[u]==low[u]){
++k; int v;
do{
v=st[top--]; instack[v]=0; bel[v]=k;
}while(u!=v);
}
}
map<string,int> mp;
signed main(){
#ifndef ONLINE_JUDGE
freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
#endif // ONLINE_JUDGE
scanf("%d",&n);
for(int i=1;i<=n;i++){
string a,b; cin>>a>>b;
mp[a]=i; mp[b]=i+n; add(i,i+n);
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
string a,b; cin>>a>>b; add(mp[b],mp[a]);
}
for(int i=1;i<=2*n;i++) if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;i++){
if(bel[i]==bel[i+n]) puts("Unsafe");
else puts("Safe");
}
return 0;
}
来源:CSDN
作者:Nightmare丶
链接:https://blog.csdn.net/qq_43544481/article/details/104360391