hdu 4685 完美匹配构图+强连通分量
// 先看poj 1904 (hdu 4685是它的升级版)
// poj 1904 题意:给n个王子和n个公主,输入王子喜欢的公主,王子只能娶他自己喜欢的人,而公主可以嫁给任何王子(只要那个王子喜欢他),且一个公主只能嫁给一个人。已知每个王子至少能取一个公主(n个王子都能娶到自己喜欢的公主)。输入: n个王子 、下面n行列出每个王子喜欢的公主、巫师给出的一组娶妻方案(一个完美匹配方案)。1 <= N <= 2000,每个王子喜欢公主的数量总和<=200000.
// 问:输出每个王子可以娶公主的最大数量和这些公主的列表(升序)。(在每个王子最大方案中,王子任意娶其中一个公主,其他王子不会单身)
// 解法:先建图,首先如果王子u喜欢公主v 建一条e(u->v)。 题目给出了一组完美匹配,对于这个匹配,王子u娶公主v,建一条e(v->u)。然后对于这个建出的图,求它的强连通分量,一个王子可以取和他在同一个强连通中的所有公主(这就是他能娶的最大人数)。
// 分析这个图:后来加的完美匹配的边e(v->u)表示公主v被王子u娶了,对于原先e(u->v)表示王子u喜欢公主v。 对于某个强连通,王子和公主的数量是相等的,如果某个王子u变心(本来完美匹配给他一个公主x)想娶某个公主v,那么就有一个边 e(u->v), 设想u现在想娶v,那么娶v的王子就要换一个人娶(当然是娶她另外一个喜欢的),而那个公主也被一个王子娶了,那么那个王子就要换一个已经被娶的公主......直到某个王子被迫娶到了第一个变心的王子丢弃的公主(这个公主x有一条边又指向了抛弃她的王子)。这样在这个图中每个王子都可以变心,娶完美匹配外的一个公主,然后那些王子被迫娶完美匹配外的其他公主。这样就能形成了一个强连通。不行的话盯着画的图加一直看就懂了。
// 输入输出量都很大,scanf 和 printf 都能超时。需要用到'外挂'输入/输出。所谓'外挂'就是自己写个函数用getchar()和putchar()输入/输出
// poj 1904
1 #include<cstdio> 2 #include<set> 3 #define read(n) n = read_n() 4 #define rep(i, n) for(int i=0;i!=n;++i) 5 #define rep1(i, n) for(int i=1;i<=n;++i) 6 using namespace std; 7 8 inline int read_n() { 9 char c=getchar();int x=0,f=1; 10 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 11 while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} 12 return x*f; 13 } 14 inline void put(int a) { 15 if(a<0){putchar('-');a=-a;} 16 if(a>9)put(a/10); 17 putchar(a%10+'0'); 18 } 19 // ----------------------------------------------------- 20 const int MAXN = 4000+5; 21 const int MAXE = 202000+5; 22 23 int num; 24 int head[MAXN]; 25 struct node { 26 int v, next; 27 } edge[MAXE]; 28 29 inline void add(int x, int y) { 30 edge[num].v = y; 31 edge[num].next = head[x]; 32 head[x] = num++; 33 } 34 35 int n; 36 int cnt, scc_cnt, t; 37 int dfn[MAXN], low[MAXN], st[MAXN], sccno[MAXN]; 38 bool vis[MAXN]; 39 40 void Tarjan(int u) { 41 dfn[u] = low[u] = ++cnt; 42 vis[u] = true; 43 st[++t] = u; 44 for(int i = head[u]; i != -1; i = edge[i].next) { 45 int v = edge[i].v; 46 if(!dfn[v]) { 47 Tarjan(v); 48 low[u] = min(low[u], low[v]); 49 } 50 else if(vis[v]) low[u] = min(low[u], dfn[v]); 51 } 52 if(dfn[u] == low[u]) { 53 ++scc_cnt; 54 int v; 55 do { 56 v = st[t--]; 57 sccno[v] = scc_cnt; 58 vis[v] = false; 59 } while(v != u); 60 } 61 } 62 63 void solve() { 64 cnt = scc_cnt = t = 0; 65 rep1(i, 2*n) vis[i] = dfn[i] = 0; 66 rep1(i, 2*n) if(!dfn[i]) Tarjan(i); 67 rep1(i, n) { 68 set<int> marry; 69 for(int j = head[i]; j != -1; j = edge[j].next) { 70 int v = edge[j].v; 71 if(sccno[i] == sccno[v]) marry.insert(v-n); 72 } 73 put(marry.size()); 74 for(set<int>::iterator j = marry.begin(); j != marry.end(); ++j) { 75 putchar(' '); 76 put(*j); 77 } 78 putchar('\n'); 79 } 80 } 81 82 int main() { 83 while(scanf("%d", &n) == 1) { 84 //read(n); 85 num = 0; 86 rep1(i, n*2) head[i] = -1; 87 int nm, x; 88 rep1(i, n) { 89 read(nm); 90 rep(j, nm) { 91 read(x); 92 add(i, x+n); 93 } 94 } 95 rep1(i, n) read(x), add(x+n, i); 96 solve(); 97 } 98 return 0; 99 }
//-------------------------------------------------------
// 题面和上一题一样。不同的是: n个王子和m个公主。且没有给出初始匹配。一个公主可以嫁给很多王子
原文地址:https://www.cnblogs.com/pupil-xj/p/11819310.html
- PaddlePaddle发布新版API,简化深度学习编程
- 13(01)总结StringBuffer,StringBuilder,数组高级,Arrays,Integer,Character
- thymeleaf模板引擎调用java类中的方法(附源码)
- 由hugepage设置导致的数据库事故(r4笔记第28天)
- 判断js引擎是javascriptCore或者v8
- Springboot系列:Springboot与Thymeleaf模板引擎整合基础教程(附源码)
- 同样的sql执行结果不同的原因分析 (r4笔记第27天)
- 情感分析的新方法,使用word2vec对微博文本进行情感分析和分类
- 垂直属性
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(二)RESTful API实战笔记(接口设计及Java后端实现)
- 13(02)总结StringBuffer,StringBuilder,数组高级,Arrays,Integer,Character
- Mybatis-Generator生成Mapper文件中<if test="criteria.valid">的问题解答
- Java开源博客My-Blog之mysql容器重复初始化的严重bug修复过程
- 负margin的原理以及应用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- [剑指Offer]面试题25: 合并两个排序的链表
- 环形链表
- 二十年前做科研你只需要检测一些基因在一些癌症细胞系表达量情况即可
- [剑指Offfer]面试题22: 链表中倒数第k个节点
- Django开发快速入门
- 三阴性乳腺癌表达数据分析笔记之PAM50
- Celery入门
- TO-do api
- 炫酷,Spring Boot + ECharts 实现用户访问地图可视化(附源码)
- 互联网大厂常考算法及套路深度解析
- 2020--Python语法常考知识点
- 为什么你画的Seurat包PCA图与别人的方向不一致?
- 用Python程序模拟300位观众,为5位嘉宾随机投票,最后按照降序排列结果
- Python知识点
- 上盘硬菜,@Transaction源码深度解析 | Spring系列第48篇