博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ1143 [CTSC2008]祭祀river 二分图匹配 最小链覆盖
阅读量:5111 次
发布时间:2019-06-13

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

欢迎访问~原文出处——



题意概括

  给出一个有向图。求最小链覆盖。


 

题解

  首先说两个概念:

    链:一条链是一些点的集合,链上任意两个点x, y,满足要么 x 能到达 y ,要么 y 能到达 x 。

    反链:一条反链是一些点的集合,链上任意两个点x, y,满足 x 不能到达 y,且 y 也不能到达 x。

  这题就是求最长反链长度。

  有两个定理:

  最长反链长度 = 最小链覆盖

  最长链长度 = 最小反链覆盖

  这题明显可以使用第一个。

  那么只需要floyd跑一跑,然后二分图匹配就可以了。

  代码比较短。


 

代码

#include 
#include
#include
#include
#include
using namespace std;const int N=100+5,N2=N*2;int n,m,match[N2];bool g[N][N],g2[N2][N2],vis[N2];bool dfs(int x){ for (int i=1;i<=n;i++){ int y=i+n; if (!vis[y]&&g2[x][y]){ vis[y]=1; if (match[y]==-1||dfs(match[y])){ match[y]=x; return 1; } } } return 0;}int main(){ memset(g,0,sizeof g); memset(g2,0,sizeof g2); scanf("%d%d",&n,&m); for (int i=1,a,b;i<=m;i++){ scanf("%d%d",&a,&b); g[a][b]=1; } for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) g[i][j]=g[i][j]||(g[i][k]&&g[k][j]); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (g[i][j]) g2[i][j+n]=1; int cnt=0; memset(match,-1,sizeof match); for (int i=1;i<=n;i++){ memset(vis,0,sizeof vis); if (dfs(i)) cnt++; } printf("%d\n",n-cnt); return 0;}

  

转载于:https://www.cnblogs.com/zhouzhendong/p/BZOJ1143.html

你可能感兴趣的文章
[NOIP2013提高组] CODEVS 3287 火车运输(MST+LCA)
查看>>
Yii2 Lesson - 03 Forms in Yii
查看>>
Python IO模型
查看>>
Ugly Windows
查看>>
DataGridView的行的字体颜色变化
查看>>
Java再学习——关于ConcurrentHashMap
查看>>
如何处理Win10电脑黑屏后出现代码0xc0000225的错误?
查看>>
局域网内手机访问电脑网站注意几点
查看>>
[Serializable]的应用--注册码的生成,加密和验证
查看>>
Day19内容回顾
查看>>
第七次作业
查看>>
SpringBoot项目打包
查看>>
Linux操作系统 和 Windows操作系统 的区别
查看>>
《QQ欢乐斗地主》山寨版
查看>>
文件流的使用以及序列化和反序列化的方法使用
查看>>
Android-多线程AsyncTask
查看>>
第一个Spring冲刺周期团队进展报告
查看>>
红黑树 c++ 实现
查看>>
Android 获取网络链接类型
查看>>
linux中启动与终止lnmp的脚本
查看>>