发现如果$B_i$和$G_j$配对,那么$B_j$又要找一个$G_k$配对,$B_k$又要找一个$G_l$配对,一直到某一个$B_x$和$G_i$配对上为止,才是不稳定的。

暴力是二分图匹配、匈牙利算法(据说可过)。仔细观察,将配对关系和潜在关系全连边,不稳定的结果则是一个环。

但是不能直接就这样找。因为无向的话,并不能保证$B_i$和$G_j$配对后就一定从$G_j$走向$B_j$。所以为了保证走向正确,需要定一下向。

将所有$G$点(糟糕的名称)连边指向他对应的配偶$B$点,然后所有$B$点将自己有的潜在关系连边指向$G$点。这样,每个$B$只有一个入度(从原来配对的$G$过来),然后再重新走向一个新的$G$点......

是不是超有道理的。。。所以每对点在不在一个简单环上,换言之,因为两点间连了一条边,只要看这条边在不在一个SCC上(边在SCC上和在简单环上是等价的,不过但两点在SCC上和在简单环上不一定等价)即可。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=1e5+,base=;
struct thxorz{int to,nxt;}G[N];
char s[];
int Head[N],frm[N],tot;
int n,m,k;
inline void Addedge(int x,int y){G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot;frm[tot]=x;}
map<ull,int> mp;
inline int Read(){
scanf("%s",s+);int len=strlen(s+);ull ha=;
for(register int i=;i<=len;++i)ha=ha*base+s[i]-'A'+;
if(mp.find(ha)==mp.end())mp[ha]=++n;
return mp[ha];
}
#define y G[j].to
int dfn[N],low[N],stk[N],instk[N],Top,cnt,bel[N];
void tarjan(int x){
dfn[x]=low[x]=++cnt,stk[++Top]=x,instk[x]=;
for(register int j=Head[x];j;j=G[j].nxt){
if(!dfn[y])tarjan(y),MIN(low[x],low[y]);
else if(instk[y])MIN(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
int tmp;
do instk[tmp=stk[Top--]]=,bel[tmp]=x;while(tmp^x);
}
}
#undef y
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(k);
for(register int i=,x,y;i<=k;++i)x=Read(),y=Read(),Addedge(x,y);
read(m);
for(register int i=,x,y;i<=m;++i)x=Read(),y=Read(),Addedge(y,x);
for(register int i=;i<=n;++i)if(!dfn[i])tarjan(i);
for(register int i=,x,y;i<=k;++i){
x=frm[i],y=G[i].to;//dbg2(x,y);
puts(bel[x]^bel[y]?"Safe":"Unsafe");
}
return ;
}

总结:一些匹配关系,可以转化为有向图,或者对图定向来完成转化,然后使用tarjan找SCC处理环问题。

BZOJ2140 稳定婚姻[强连通分量]的更多相关文章

  1. BZOJ2140: 稳定婚姻

    题解: 题意就是求二分图的必须边. 我们有结论: 在残量网络上跑tarjan,对于一条边(u,v) 如果该边满流||scc[u]==scc[v],那么该边是可行边. 因为如果scc[u]==scc[v ...

  2. BZOJ2140: 稳定婚姻(tarjan解决稳定婚姻问题)

    2140: 稳定婚姻 Time Limit: 2 Sec  Memory Limit: 259 MBSubmit: 1321  Solved: 652[Submit][Status][Discuss] ...

  3. BZOJ_2140_稳定婚姻_强连通分量

    BZOJ_2140_稳定婚姻_强连通分量 Description 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚 姻问题的专家认为,是与简化离 ...

  4. 【bzoj2140】: 稳定婚姻 图论-tarjan

    [bzoj2140]: 稳定婚姻 哎..都是模板题.. 一眼看过去 哇 二分图哎 然后发现好像并不能匈牙利算法 自己xjb画两张图,发现二分图左向右连配偶的边,然后右向左连交往过的边 然后如果Bi G ...

  5. 【BZOJ2140】稳定婚姻 Tarjan

    [BZOJ2140]稳定婚姻 Description 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. ...

  6. 洛谷 P1407 [国家集训队]稳定婚姻

    洛谷 这个题面很有意思,像我这样的菜鸡,完全不需考虑婚姻的稳定 性 问题. tarjan裸题,直接讲算法吧: 原配夫妻之间分别连一条边,小情人之间反向连边. 这时候我们会发现一个性质,如果婚姻稳定,那 ...

  7. 稳定婚姻(tarjan)

    传送门 这道题一开始可能以为是二分图匹配……?不过后来发现和二分图没啥大关系. 简单分析之后发现,把夫妻之间连边(男性向女性连边),之后再将每对曾经是情侣的人连边(女性向男性连边),当然以上的方向可以 ...

  8. [Luogu] P1407 [国家集训队]稳定婚姻

    题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的姗姗和男友谈恋爱半年就结婚,结婚不到 ...

  9. 2140: 稳定婚姻 - BZOJ

    Description 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的姗姗和男友谈恋爱半年就 ...

随机推荐

  1. du 和 df命令

    测试环境数据库收到磁盘报警时,需要清理部分磁盘空间 df -h 查看整个磁盘占有 找到对应目录 查看每个文件夹占有磁盘量: sudo du -h --max-depth=1 data/ --max-d ...

  2. 洛谷 题解 P2010 【回文日期】

    因为有8个字符,所以可得出每一年只有一个回文日期. 因此只要判断每一年就行了. 做法: 我们先把年倒过来,例如2018年就倒为8102,就得出8102就是回文日期的后四个字符,我们只要判断一下有没有这 ...

  3. 《你必须知道的495个C语言问题》读书笔记之第1-2章:声明和初始化

    1. C标准中并没有精确定义数值类型的大小,但作了以下约束: (1) char类型可以存放小于等于127的值: (2) short int和int可以存放小于等于32767的值: (3) long i ...

  4. axios对请求各种异常情况处理的封装

    前端网络请求封装 前端采用了axios来处理网络请求,为了避免在每次请求时都去判断各种各样的网络情况,比如连接超时.服务器内部错误.权限不足等等不一而足,我对axios进行了简单的封装,这里主要使用了 ...

  5. Oracle学习记录(一)

    一.Oracle历史 于1977年拉里埃里森和他三个朋友成立了软件研发公司,并在之后给中央情报局开发了命名为Oracle而出名,并在之后将公司名改为Oracle.1989年以甲骨文命名进入中国. Or ...

  6. Pandas 读取超过 65536 行的 Excel 文件

    Excel 文件的格式曾经发生过一次变化,在 Excel 2007 以前,使用扩展名为 .xls 格式的文件,这种文件格式是一种特定的二进制格式,最多支持 65,536 行,256 列表格.从 Exc ...

  7. python+selenium+chrome实现自动登录百度

    #python3.4+selenium3.5+chrome版本 63.0.3239.132+chrome驱动chromedriver.exe #实现自动登录百度 from selenium impor ...

  8. 怎样获取xhr的当前状态

    一个XMLHttpRequets实例从创建到发起请求再到获取数据, 期间会有一些中间状态, 这些状态是必要的, 我们可以通过判断这些状态值来进行不同的动作. xhr中获取请求状态的属性是: xhr.r ...

  9. hdu 2821 学习一点dfs的小技巧吧。。 还是自己太弱了

    #include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c ...

  10. HTTP协议探究(三):HTTPS

    一 复习与目标 1 复习 代理:转发通信数据(一般协议不变,作为中间人,可对报文进行过滤修改) 网关:转发通信数据(协议改变,作为资源拥有者) 隧道:转发通信数据(协议不变,作为管道,不对报文进行过滤 ...