洛谷 1407 [国家集训队]稳定婚姻 题解(强连通分量,建图,思维)

本文主要是介绍洛谷 1407 [国家集训队]稳定婚姻 题解(强连通分量,建图,思维),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原题链接:
luogu
bzoj

题意简述

给定 2 n 2n 2n个人,一些情侣关系,和 n n n对夫妻关系。定义一对"不安全的"夫妻为:即使离婚,但是算上旧情复燃(就是那些情侣)的关系,依然珂以让每个人都有伴侣(也就是还能找到 n n n对伴侣)。输出 n n n行,按照给定夫妻的顺序,输出每对夫妻关系是否安全。安全输出Safe,不安全输出Unsafe

数据

输入
n//夫妻对数
girl boy
girl boy
...
girl boy
//n行,每行描述一对夫妻关系。保证没有开后宫的,也没有单身的。
//是字符串形式哦!!!!!
m//情侣对数(导致婚姻不安全的罪魁祸首)
girl boy
girl boy
...
girl boy
//m行,每行描述一对情侣关系,不保证没有开后宫的(情侣嘛,一个人有很多是正常的)。
//当然,也珂能有人没有情人
//同样也是字符串形式,但是保证是上面出现过的。
输出
ans
ans
...
ans
//n行
//ans="Safe"或"Unsafe",注意大小写
//对于每对夫妻,输出答案
样例

输入

2
Melanie Ashley
Scarlett Charles
1
Scarlett Ashley

输出

Safe
Safe

输入

2
Melanie Ashley
Scarlett Charles
2
Scarlett Ashley
Melanie Charles

输出

Unsafe
Unsafe

思路

题面很有意♂思

(很明显要建图吧。。。情侣或夫妻都连一条无向边。这很容易想到)
建完图后,想想:什么时候会出现不稳定的婚姻呢?
不难想到,就是一对婚姻关系在偶环上的时候。
珂是我们如何找环呢?
此时我们就要有梦想。我们会 T a r j a n Tarjan Tarjan求强连通分量,珂是我们不会在无向图上找环。所以此时就要用到建图里面一个(比较)常用的思路:给无向图定向。

现在假设有 4 4 4个人,关系长这样:
blog1.jpg
(红色女的,蓝色男的,自古红蓝出cp嘛)
黑 色 黑色 是夫妻边, 绿 色 \color{#00ff00} {绿色} 绿是情侣边)
显然这样是不安全的,两对夫妻都不安全。
然后我们要让这四个人组成一个强连通分量。不用说,肯定要这样配:
blog2.jpg
或者这样:
blog3.jpg
总之有一点,那就是:
绿色边的方向 和 蓝色边的方向 是相反的!
比如,
绿色是 g i r l girl girl b o y boy boy,黑色就得( d e ˇ i děi deˇi)是 b o y boy boy g i r l girl girl
绿色是 b o y boy boy g i r l girl girl,黑色就得是 g i r l girl girl b o y boy boy
当然,我也忘了我代码里是怎么样的了,反正只要是反的就珂以了。

这样建完图,跑一遍强连通分量就好了。最后就是判一下一对夫妻边连接的两个点是否在同一个强连通分量里面即珂。如果是,输出Unsafe,否则输出Safe

代码:

#include<bits/stdc++.h>
using namespace std;
namespace Flandle_Scarlet
{#define N 100100class Graph{public:int *head;int EdgeCount;struct Edge{int To,Label,Next;}*Ed;int MAX;void SET(int len){MAX=(len<<1)+100;Ed=new Edge[MAX];head=new int[MAX];memset(head,-1,sizeof(int)*MAX);memset(Ed,-1,sizeof(Edge)*MAX);EdgeCount=0;}void clear(){memset(head,-1,sizeof(int)*MAX);memset(Ed,-1,sizeof(Edge)*MAX);EdgeCount=0;}void AddEdge(int u,int v,int w){++EdgeCount;Ed[EdgeCount]=(Edge){v,w,head[u]};head[u]=EdgeCount;}void Add2(int u,int v,int w){AddEdge(u,v,w);AddEdge(v,u,w);}int Start(int u){return head[u];}int To(int u){return Ed[u].To;}int Label(int u){return Ed[u].Label;}int Next(int u){return Ed[u].Next;}}G;map<string,int> bid,gid;//处理一下字符串,由于我懒,我就直接用了mapchar b[N][10],g[N][10];int n,m;void Input(){scanf("%d",&n);G.SET(100000);for(int i=1;i<=n;++i)//boy to girl{scanf("%s%s",g[i],b[i]);bid[b[i]]=i;gid[g[i]]=i;G.AddEdge(i,i+n,1);}scanf("%d",&m);for(int i=1;i<=m;++i)//girl to boy{char t1[10],t2[10];scanf("%s%s",t2,t1);int u=bid[t1],v=gid[t2];G.AddEdge(v+n,u,1);}}//normalint DFSid[N],low[N],time=0;bool In[N];stack<int>STK;int SCCid[N],SCCcnt=0;//additionint size[N];void Tarjan(int u){DFSid[u]=low[u]=++time;STK.push(u);In[u]=1;for(int i=G.Start(u);~i;i=G.Next(i)){int v=G.To(i);if (!DFSid[v]){Tarjan(v);low[u]=min(low[u],low[v]);}else if (In[v]) low[u]=min(low[u],low[v]);}if (DFSid[u]==low[u]){int top;++SCCcnt;do{top=STK.top();STK.pop();In[top]=0;SCCid[top]=SCCcnt;++size[SCCcnt];} while (top!=u);}}【模板】强连通分量void Soviet(){for(int i=1;i<=(n<<1);++i){if (!DFSid[i]){Tarjan(i);}}for(int i=1;i<=n;++i){int u=bid[b[i]];int v=gid[g[i]]+n;if (SCCid[u]==SCCid[v])//在一个SCC里面{puts("Unsafe");//那就是不安全的}else{puts("Safe");//否则就是安全的}}}void IsMyWife(){if (0){freopen("","r",stdin);freopen("","w",stdout);}Input();Soviet();}
};
int main()
{Flandle_Scarlet::IsMyWife();return 0;
}

回到总题解界面

这篇关于洛谷 1407 [国家集训队]稳定婚姻 题解(强连通分量,建图,思维)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/214754

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

poj 3181 网络流,建图。

题意: 农夫约翰为他的牛准备了F种食物和D种饮料。 每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。 问最多能有多少头牛可以同时得到喜欢的食物和饮料。 解析: 由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。 如下建图: s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t 所以分配一下点: s  =  0, 牛1= 1~

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

跨系统环境下LabVIEW程序稳定运行

在LabVIEW开发中,不同电脑的配置和操作系统(如Win11与Win7)可能对程序的稳定运行产生影响。为了确保程序在不同平台上都能正常且稳定运行,需要从兼容性、驱动、以及性能优化等多个方面入手。本文将详细介绍如何在不同系统环境下,使LabVIEW开发的程序保持稳定运行的有效策略。 LabVIEW版本兼容性 LabVIEW各版本对不同操作系统的支持存在差异。因此,在开发程序时,尽量使用

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

C - Word Ladder题解

C - Word Ladder 题解 解题思路: 先输入两个字符串S 和t 然后在S和T中寻找有多少个字符不同的个数(也就是需要变换多少次) 开始替换时: tips: 字符串下标以0开始 我们定义两个变量a和b,用于记录当前遍历到的字符 首先是判断:如果这时a已经==b了,那么就跳过,不用管; 如果a大于b的话:那么我们就让s中的第i项替换成b,接着就直接输出S就行了。 这样

【秋招笔试】9.07米哈游秋招改编题-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新 🍄 题面描述等均已改编,如果和你笔试题看到的题面描述

LeetCode 第414场周赛个人题解

目录 Q1. 将日期转换为二进制表示 原题链接 思路分析 AC代码 Q2. 范围内整数的最大得分 原题链接 思路分析 AC代码 Q3. 到达数组末尾的最大得分 原题链接 思路分析 AC代码 Q4. 吃掉所有兵需要的最多移动次数 原题链接 思路分析 AC代码 Q1. 将日期转换为二进制表示 原题链接 Q1. 将日期转换为二进制表示 思路分析