博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Luogu P1407 [国家集训队]稳定婚姻 (二分图写法)
阅读量:5214 次
发布时间:2019-06-14

本文共 2267 字,大约阅读时间需要 7 分钟。

RT,这是一道强联通分量。

而我一个热爱匈牙利的OIer
默默敲下了...

#include
#include
#include
#include
#include
using namespace std;int n,m,cnt,vis[100005],match[100005],head[100005],now[100005];map
boy,girl;struct edge{ int u,v,next;bool dis;}e[100005];inline void add(int u,int v){ e[++cnt].v=v; e[cnt].u=u; e[cnt].next=head[u]; head[u]=cnt;}inline bool dfs(int u){ for(int i=head[u];i!=-1;i=e[i].next){ if(e[i].dis)continue; int v=e[i].v; if(!vis[v]){ vis[v]=1; if(match[v]==-1||dfs(match[v])){ match[v]=u; return 1; } } } return 0;}int main(){ memset(match,-1,sizeof(match)); memset(head,-1,sizeof(head)); scanf("%d",&n); for(int i=1;i<=n;i++){ string s,t; cin>>s>>t; boy[s]=i; girl[t]=i; add(boy[s],girl[t]); now[i]=cnt; } scanf("%d",&m); for(int i=1;i<=m;i++){ string s,t; cin>>s>>t; add(boy[s],girl[t]); } for(int i=1;i<=n;i++){ memset(match,-1,sizeof(match)); int tot=0; e[now[i]].dis=1; for(int j=1;j<=n;j++){ memset(vis,0,sizeof(vis)); tot+=dfs(j); } if(tot==n){ printf("Unsafe\n"); } else{ printf("Safe\n"); } e[now[i]].dis=0; }}

然后各种常数优化

NM的register,hash,读入优化
P用么得
然后去翻了洛谷题解
大概基本上都是强联通分量的
但是二分图
然后重拾了信心QwQ
但是那位巨佬的二分图建图是把汉字和妹子统一编号的,我不习惯那样
所以抄不了题解,只好自己刚
心态崩盘后仔细研读了那位巨佬的题解
发现根!本!不!是!一般的二分图写法
因为一开始是匹配好的
用我的码风来描述就是:

#include
#include
#include
#include
#include
using namespace std;int n,m,cnt,vis[100005],match[100005],head[100005],dis;map
boy,girl;struct edge{ int u,v,next;}e[100005];inline void add(int u,int v){ e[++cnt].v=v; e[cnt].u=u; e[cnt].next=head[u]; head[u]=cnt;}inline bool dfs(int u){ for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(u==dis&&v==dis)continue; if(!vis[v]){ vis[v]=1; if(match[v]==-1||dfs(match[v])){ return 1; } } } return 0;}int main(){ memset(match,-1,sizeof(match)); memset(head,-1,sizeof(head)); scanf("%d",&n); for(int i=1;i<=n;i++){ string s,t; cin>>s>>t; boy[s]=i; girl[t]=i; match[i]=i; } scanf("%d",&m); for(int i=1;i<=m;i++){ string s,t; cin>>s>>t; add(boy[s],girl[t]); } for(int i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); match[i]=-1; dis=i; if(dfs(i)){ printf("Unsafe\n"); } else{ printf("Safe\n"); } match[i]=i; }}

转载于:https://www.cnblogs.com/Y15BeTa/p/11298438.html

你可能感兴趣的文章
最大公约数求解
查看>>
网卡bond技术
查看>>
UITabbarController的UITabbarItem(例:"我的")点击时,判断是否登录
查看>>
机器学习之支持向量机(一):支持向量机的公式推导
查看>>
对【SQL SERVER 分布式事务解决方案】的心得补充
查看>>
UNIX基础知识之输入和输出
查看>>
【洛谷 P1666】 前缀单词 (Trie)
查看>>
python之装饰器
查看>>
对称加密和非对称加密
查看>>
数据库锁机制及乐观锁,悲观锁的并发控制
查看>>
图像处理中双线性插值
查看>>
RobHess的SIFT代码解析之RANSAC
查看>>
03 线程池
查看>>
201771010125王瑜《面向对象程序设计(Java)》第十三周学习总结
查看>>
java中内部类的讲解
查看>>
手机验证码执行流程
查看>>
python 基础 ----- 变量
查看>>
设计模式课程 设计模式精讲 2-2 UML类图讲解
查看>>
为块级元素添加链接
查看>>
Silverlight 的菜单控件。(不是 Toolkit的)
查看>>