博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[eJOI2018]元素周期表
阅读量:5146 次
发布时间:2019-06-13

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

\((r_1,c_1),(r_2,c_1),(r_1,c_2)\)三个格子存在就说明\((r_2,c_2)\)存在,如果我们将\(r_1,c_2,c_1,r_2\)都看成一些点的话,那么这个关系就非常类似于\(r_1\)\(c_1\)联通,\(r_2\)\(c_1\)联通,\(c_2\)\(r_1\)联通,那么就说明\(r_2\)\(c_2\)联通

于是我们将每个格子\((x,y)\)看成一些边,连接\(x\)行和\(y\)列,显然这张图是一个二分图,我们的目标就是将其补成一个完全二分图,即有\(n\times m\)条边

我们把已经有的\(q\)条边连上,发现我们不需要代价就能连的边都是在同一个联通块里的,我们补全所有不需要代价的边最多也只能把图补成几个完全二分图的子图

而同一个联通块内的边不需要代价,所以我们利用尽量少的边使得这张图完全联通就好了,显然需要连得边数就是联通块的个数\(-1\),并查集维护一下就好了

代码

#include
#define re registerinline int read() { char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;}const int maxn=2e5+5;int fa[maxn<<1],n,m,q;inline int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}inline void merge(int x,int y) { int xx=find(x),yy=find(y); if(xx==yy) return;fa[xx]=yy;}int main() { n=read(),m=read(),q=read(); for(re int i=1;i<=n+m;++i) fa[i]=i; for(re int x,y,i=1;i<=q;i++) x=read(),y=read(),merge(x,y+n); int ans=0; for(re int i=1;i<=n+m;i++) if(find(i)==i) ans++; printf("%d\n",ans-1); return 0;}

转载于:https://www.cnblogs.com/asuldb/p/11488655.html

你可能感兴趣的文章
Android Studio 生成 Xutils3 注入的插件
查看>>
8th week blog 2
查看>>
LeetCode之Add Two Numbers
查看>>
Noj(1070)
查看>>
sql server 由于登入失败而无法启动服务
查看>>
RST_n的问题
查看>>
欢迎来我的#百度相册#时光轴,坐上时光机,与我一起穿梭时空!
查看>>
------结对作业代码复审-----
查看>>
ASP.NET 获得当前网页名字
查看>>
windows pear 安装
查看>>
RabbitMQ安装详解(centos6.8)(转自:http://www.cnblogs.com/zhen-rh/p/6862350.html)
查看>>
hdu 2565 放大的X
查看>>
前缀表达式
查看>>
java基础面试题常出现(一)
查看>>
练习jQuery
查看>>
Java面试题--基础知识部分
查看>>
编译器结构
查看>>
jvm 指令重排
查看>>
PL/SQL 游标详解
查看>>
php随机输出验证码
查看>>