随笔分类 - 图论·二分图
摘要:题意: 有 2*n个同学,n男n女,知道了 有 m 对 男女之间木有吵过架,现在这 n 个女生要找对象,要求没有和她吵过架或者没有和她的一个朋友吵过架, 当 n 个女生都找到对象的时候算作一轮,然后重新找,满足每个女生都不能找和上次一样的对象,问最多能进行多少轮。分析: 将是朋友关系的女生放到一个集合,用来降低建图的时间复杂度。#include <stdio.h>#include <string.h>#define maxn 102#define clr(x)memset(x,0,sizeof(x))int f[maxn];int search(int x){ retu
阅读全文
摘要:题意:在一个n*n的矩阵中,找n个数使得这n个数都在不同的行和列里并且要求这n个数中的最大值和最小值的差值最小。分析: 二分枚举差值,如果满足完全匹配则该差值符合。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))int g[105][105];int link[105];int v[105];int n;int res;int mid,p;int find(int x){ int i; for(i=1;i<=n;i++) { if((!v[i])&&(g[x
阅读全文
摘要:题意: 有 n 只cat和 m只dog,有 c 个小朋友,知道了每个小朋友喜欢的动物和不喜欢的动物,现在可以将其中一些动物移走,如果剩下的动物中有 某个小朋友喜欢的而没有他不喜欢的,这个小朋友就会很高兴,问最多可以让多少小朋友高兴。分析: 二分图最大独立集,如果某个小朋友和另一个小朋友有冲突即其中一个小朋友喜欢的动物是另一个小朋友讨厌的,或者他讨厌的是另一个小朋友 喜欢的话,就在两个小朋友之间连一条边,求出最大匹配, 最大独立集= 总权- 最大匹配/2(因为有重复)#include<stdio.h>#include<string.h>#define clr(x)mems
阅读全文
摘要:题意: 有N 个人,知道了每个人知道的信息,和它最多能告诉别人的信息数目,问编号为 m 的人最多能知道的信息条数是多少。分析: 由于信息的编号比较大,所以先需要进行离散化。 每个人和自己知道的每个信息之间都有一条边相连, 每个人匹配容量为 他最多能告诉别人的信息数目。#include<stdio.h>#include<string.h>#define maxn 222#define clr(x)memset(x,0,sizeof(x))int cap[maxn]; int map[maxn][maxn];int vlink[maxn]; ...
阅读全文
摘要:题意: 有 n 个人,他们之间的关系有四种,给出一些关系 a,b 表示b 知道 a,现在想把这些人分成两组,每个组里面所有人都相互知道,如果可以分成这两组, 找出两组人数相差最少的情况。分析:如果 a 和 b 不是相互知道,就在a,b之间连一条双向边,表示a 和b 绝不能分在一个组里 建好图之后,进行染色,判断是否是二分图,如果不是二分图,肯定不存在符合条件的情况 染色的同时,记录每个连通块中每个部分的个数,并记录路径 用 01 背包标记所有存在的状态,找到差值最小的情况#include<stdio.h>#include<string.h>#define clr(x)m
阅读全文
摘要:题意: 已知有n个插头,知道了m个用电器和其能插的插座型号,和k个转换器,问最少有多少个用电器无法连接到相应的插座上。适配器的作用: 例如:有插座C 转换器B(插孔) C(插头) 如果用电器能插到插座B上,那么通过转换器,它就能插到C上。分析: 建图的时候递归建图,如果用电器能直接连到某个插座或通过转换器间接查到某个插座上,就在期间连一条边,求出最大匹配,用总数减去即为剩下的无法连接个数的最小值#include<cstdio>#include<cstring>#include<string>#include<map>#include<ios
阅读全文
摘要:题意: 知道了一些出租车任务的时间,每个任务需要一辆出租车从该任务的起点到终点,有些任务有时间上的冲突,问最少需要多少 辆出租车能完成任务。分析: 最小路径覆盖。 如果两个任务没有冲突,就在两个任务之间连一条边,找出最少的路径条数来覆盖所有点,(一条路径只需要一辆车)。 最小路径覆盖 = 总权 - 最大匹配#include<stdio.h>#include<string.h>struct node{ int to,next;}e[1000000];int tot;int head[505];void add(int s,int u){ e[tot].to=u; e[to
阅读全文
摘要:题意:一个有 N 个节点的有向无环图, 已知有 M 条边,问最少放多少机器人可以使得图中任何一点都至少可以被其中一个机器人达到。分析: 最小路径覆盖。 因为可以经过一些点到达另一些顶点,所以需要传递闭包将每个点可达的顶点都连上边,然后求最小路径覆盖。 最小路径覆盖 = 总权 - 最大匹配#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))int g[505][505];int link[505];int v[505];int n;int find(int x){ int i; for
阅读全文
摘要:题意: 有 N 个蚂蚁,N 个苹果,要在每个蚂蚁和一个相应的苹果之间连边,问如何给蚂蚁分配苹果,可以使这些边不相交。分析:应为在最小权值匹配的情况下满足没有边相交,可以简单证明,假设最小完备匹配中有两条线段AC和BD相交于点E,此时我们可以不连接AC和BD而去连接AD和BC,由于AE+DE>AD和BE+CE>BC,所有我们可以得出新连接的边的权值和一定比原来的边的权值和小,这样就可以得到一种权值和更小的匹配,这原来的匹配是最小带权和的匹配矛盾, 因此最小带权和的匹配中不会出现有两条线段相交的情况。code:#include<stdio.h>#include<str
阅读全文
摘要:题意: 有 p 个水手和一个章鱼,章鱼有 n 个脚,知道了所有单位的坐标,和船长以及船员的速度,船长想去攻击章鱼的头部,但是只有在章鱼所有的脚都被水手控制的情况下才会开始朝章鱼头部进攻,问如何分配水手控制的触须,才能在最短时间内是船长攻击到其头部。分析: 二分枚举船员移动的时间ti, 如果水手与某个触须接触所要的时间小于 ti,就在该水手与该触须之间连一条边,找出满足水手与触须最大匹配等于 n 的最小时间,最后加上船长移动到章鱼头部需要的时间即为答案。#include<cstring>#include<cstdio>#include<cmath>#defin
阅读全文
摘要:题意: 一些男生和一些女生之间有爱慕关系,已知一些男生和女生的爱慕关系,学校想从这些学生中找出一些的学生满足这些学生之间彼此都没有爱慕的关系--!~,问找出的这个集合最多可以有多少人。分析:求二分图的最大独立集最大独立集=顶点数-最小点覆盖 由于这道题中爱慕关系是相互的,可以看成是无向图,可以将每个人拆成两个点 由于是无向图 ,最小点覆盖数=最大匹配/2#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))struct node{ int to,next;}e[10000];int t
阅读全文
摘要:题意:有n 个小巫师,还有 m 个小精灵 ,还有 K 个大树,巫师可以用 霜冻新星杀死小精灵,但是每使用一次都有一定 的技能冷却时间,而且小精灵必须在攻击范围内。分析: 二分答案,即枚举符合条件的时间,满足所有小精灵被KO,由于每个巫师能够杀死多个小精灵,所以可以用到二分 图多重匹配,如果所有小精灵都找到匹配,那么该时间符合, 最麻烦的是建图,两个人之间必须不能有树阻挡,在 计算两个人所在线段与 树相交的时候 可以先计算点(树的坐标)到线段(巫师与小精灵连线)的最短距离,如果该 距离小于树的半径,那么该巫师和小精灵能够形成匹配。View Code #include<stdio.h>
阅读全文
摘要:题意: 给一个n*m的方格,里面放着横竖的单词,问从里面最多可以选出多少组单词并使他们互不冲突。分析: 二分图最大独立权集,求出最大匹配数,总结点数减去最大匹配即为答案。View Code #include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))char map[2002][2002];int a[2002][2002];int link[505];int v[505];struct node{ int to,next;}q[1000000];int head[2002];int tot
阅读全文
摘要:题意:有一个n * m的矩阵,每个元素都是非负的,每一行,每一列的边缘都有一个按钮(即n + m个),对应着第1行,第2行,第3行,…,第n行,第1列,第2列,第3列,…,第m列。每当他按下某个按钮,那么对应的一行或者一列的所有元素将减去1,值为0的元素不受到影响。他想知道,他最少需要按多少次按钮,能够将整个矩阵都变成0。分析: 有点类似最小点权覆盖,以行为 X 集合, 以列为 Y 集合,以 g[i][j] 为边权建立二分图,完美匹配下的最大权值即为答案, 最大权匹配算法要保证左右集合相等,因此在点不够的情况下要补点!!!View Code #include<stdio.h>#in
阅读全文
摘要:题意: 有 n 条鱼,雄的会攻击他认为是雌的鱼,一条鱼一旦被攻击,就会生下一定数量的孩子,每条鱼只能被攻击一次, 问最后最多可以生下多少孩子。分析: 因为每条鱼只能被攻击一次,正好符合二分图的性质,此题只要找出完全匹配下的最优匹配即可。模板一:View Code #include<stdio.h>#include<string.h>#define INF 0x1f1f1f1fint sx[101],sy[101];int lx[101],ly[101];char a[102][102];int map[102][102];int link[101];int va[101
阅读全文
摘要:题意: 一共有 n 个任务, m 台机器, 知道了每个机器处理每个任务的时间,一个任务只有在处理完之后才能处理其他任务,问你最少需要多少时间, 才能做完所有的任务。分析: 以 任务为 X 集合 第 i 个任务在第 j 台机器 倒数第 k 个完成为 Y 集合,找到完全匹配下的最小权匹配,此题构图方法依然是 拆点。View Code #include<stdio.h>#include<string.h>#define INF 0x1f1f1f#define clr(x)memset(x,0,sizeof(x))int sx[55],sy[2550];int lx[55],l
阅读全文
摘要:题意: 给你一个包含 n 个城市的距离,并告诉你其中的一些路的距离,让你用一些环去覆盖所有点,且每个点只能覆盖一次,问环的最小城市多少。分析:每个点只出现一次,而每一个点对应一个入的边和一个出的边,可以将入边放入 X 集合, 出边放入 Y 集合,二分该图,求其完全匹配下的最小权值 匹配。View Code #include<stdio.h>#include<string.h>#define INF 0x1f1f1f#define clr(x)memset(x,0,sizeof(x))int sx[202],sy[202];int lx[202],ly[202];int
阅读全文
摘要:题意: 给你一个图HH. .m. . . . .. . . . .. . . . .mm. .Hm代表人 H 代表房子,一个人只能进一个房子,问你如何安排人进房,使得总步数最小。分析: 可以用最小费用最大流,也可以用二分图最优匹配。#include<stdio.h>#include<string.h>#define min(a,b)(a)<(b)?(a):(b)#define INF 0x1f1f1f#define maxn 105#define clr(x)memset(x,0,sizeof(x))int abs(int x){ return x>0?x:
阅读全文
摘要:题意: 给你 n 个 男的 ,m 女的,男的之间都是相互认识的,女的同样,告诉你一些男女关系,让你找出最多的人使其中任意一个人都相互认识。分析: 同上一题。。。/*独立集:任意两点都不相连的顶点的集合独立数:独立集中顶点的个数完全子图:任意两点都相连的顶点的集合最大完全数:最大完全子图中顶点的个数最大完全数=原图的补图的最大独立数最大独立数=顶点数-最大匹配数这样,就可以求出最大完全数完全图G就是指图G的每个顶点之间都有连边。这样,令完全图G的阶|G|=N,那么完全图G具有如下性质:1.图G有(N-1)*N/2条边。2.图G上的生成树有N^(N-2)种。3.★图G的补图G'中没有边。由
阅读全文
摘要:题意: 给你 n 个人,和四个条件,两个人只要满足其中任意一个条件就不能成为夫妻, 问从中最多能找出多少人使得他们任意两个人都不可能成为夫妻。分析: 二分图最大独立权集,把男的放到一个集合 ,女的放到另一个几何,二分该图, 如果两个人能成为夫妻,则他们构成一个匹配,找出最大匹配,最大独立全集即为 总人数 - 最大匹配View Code #include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))struct node{ int to,next;}q[200005];int head[505]
阅读全文


浙公网安备 33010602011771号