随笔分类 -  图论·连通图

摘要:2—sat建图总结1.元素关系有以下11种A[x]NOT A[x]A[x] AND A[y]A[x] AND NOT A[y]A[x] OR A[y]A[x] OR NOT A[y]NOT (A[x] AND A[y])NOT (A[x] OR A[y])A[x] XOR A[y]NOT (A[x] XOR A[y])A[x] XOR NOT A[y] And 结果为1:建边 ~x->y, ~y->x (两个数都为1)And 结果为0:建边 y->~x , x->~y(两个数至少有一个为0)OR 结果为1:建边 ~x->y , ~y->x(两个数至少有一个为 阅读全文
posted @ 2012-11-03 23:57 'wind 阅读(764) 评论(0) 推荐(0)
摘要:题意:判断矩阵是否符合条件:思路:建图方式 对于&操作, if(c=1) 当a为1时b必须为1,当b为1时a必须为1; 当a为0时a必须为1,当b为0时b必须为1,否则不可能为1 else{ 当a为1时b必须为0,当b为1时a必须为0; 当a为0时一定为0没有矛盾产生,当b为0时一定为0没有矛盾产生; } 对于|操作 if(c=0) 当a为0时b必须为0,当b为0时a必须为0; 当a为1时a必须为0,当b为1时b必须为0,否则不可能为0 else{ 当a为0时b必须为1,当b为0时a必须为1; 当a为1时一定为1没有矛盾产生,当b为1时一定为1... 阅读全文
posted @ 2012-10-25 07:46 'wind 阅读(448) 评论(0) 推荐(0)
摘要:题意: 有n个人正在玩游戏,完成一个传递的游戏,假如A传递到B,B传递给C,则C拥有2的传递值,C是胜利者,如果C又传递回A,那么A,B,C三者都拥有传递值为2的 胜利者,输出最后获得的最多传递值和拥有该传递值的人。分析:强连通缩点后用树形DFS找到最大值。#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define clr(x) memset(x,0,sizeof(x))#define min(a,b)(a)<(b)?(a):(b)#defin 阅读全文
posted @ 2012-10-08 23:26 'wind 阅读(194) 评论(0) 推荐(0)
摘要:题意: 给出一个有n 个节点的和m 条单向边,问图中是否任意两点都是连通的,这里连通的定义为:u,v连通,则存在一条从u到v的边或存在一条从v到u的边。分析:因为在一个强连通分量内部的点是两两可达的,所以可以先对所有的强连通分量缩点,即把强连通分量内部的点看成是一个点。如果两点不可达那么在拓 扑排序时,该两点谁也不是谁的前驱和后继,所以在拓扑排序时只要同时出现至少两个入度为0的点,那么这些点一定互不可达,所以只要判断拓扑的方式 是否唯一即可。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeo 阅读全文
posted @ 2012-10-03 17:39 'wind 阅读(351) 评论(0) 推荐(0)
摘要:题意: 有 n 个教室组成一个连通图,知道了m条无向边,现在要去掉一条边使得这些教室分成两个连通的集合,问是否可以做到,如果可以找出两个集合人数 的最小差值。分析: 因为所有的在同一个双连通分量中的人都必须在一个集合里,可以先求出所有的双连通分量并染色,然后用树形DP求出最小差值即可。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))#define min(a,b)(a)<(b)?(a):(b)#define maxn 100005#define maxm 1000005st 阅读全文
posted @ 2012-10-02 13:27 'wind 阅读(246) 评论(0) 推荐(0)
摘要:题意:有 n 座城市和 m 条有向边,现在要把这 n 座城市分成一些洲,要求: 如果城市 u,v 之间可以互达则两座城市要分在一个洲里面, 每个洲里面的任意两个城市 u,v之间至少需要存在一条边,问做少能够分成多少个洲。分析:先求强连通分量并进行缩点,重新建图,如果两个强连通分量之间如果存在一条边连接其中一个强连通分量内部的一个点和另一个强 连通分量内部的一个点则连一条边从第一个强连通分量到第二个强连通分量,求出最小路径覆盖即为答案。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x) 阅读全文
posted @ 2012-10-01 21:07 'wind 阅读(459) 评论(0) 推荐(0)
摘要:题意: 已知有 n个农场,知道了每个农场的坐标,有两个中转站 s1,s2,每个农场和其中一个中转站相连, 有 A 对hate关系 a,b 表示 a 和 b 农场不能和同一个中转站相连,有B对Fs 关系a,b 表示 a和 b农场必须和同一个中转站相连, 求一种连接方案,在满足条件 A,B的条件下,图中任意两个农场的最大距离最小。分析:i表示第 i 个农场和中转站 s1 相连,i + n 表示第 i 个农场和中转站 s2 相连, 建图: 在 A 条件中,对于每对关系i , j 连边i-> j + n i + n ->j j ->i + n j + n ->i表示 i 和 j 阅读全文
posted @ 2012-10-01 14:49 'wind 阅读(170) 评论(0) 推荐(0)
摘要:题意:已知有 2*n把钥匙,这些钥匙两两一组,每组只能用其中的一把钥匙,有 m 个门,每个门上有两把锁,只要有一把锁被打开门就可以被打开, 一个门上可能是两把相同的锁,不同的门上也有可能有相同的锁,给出门的顺序,问最多可以打开多少扇门。分析: 每种钥匙都有两种状态,用 or 不用, kn = 2*n i 表示 第 i 把钥匙被用,i + kn 表示 不用第 i 把钥匙, 在给出的要是分组中的 i , j 连边 i - > j + kn j->i+ kn 表示 如果用 i 钥匙则 j 钥匙不能用,如果用 j钥匙则 i 钥匙不能用 2 分枚举要开的前 k 个门,对于每个门上的两把锁 i 阅读全文
posted @ 2012-10-01 13:15 'wind 阅读(172) 评论(0) 推荐(0)
摘要:题意:有 n对新人结婚,只有一个牧师,知道了每个婚礼的开始时间 s,和结束时间 t 和需要牧师的主持时间 las,牧师可以选在在[s,s+las]或[t-las,t]两个时间段内主持,问是否存在一个时间安排,使得所有新人都可以得到牧师的主持。分析: 每一个婚礼主持时间都是两种状态,每个婚礼之间的时间可能会互相限制,可以用2-sat判断是否冲突。建图: 每个婚礼的两个时间段 i = [s,s+las],i +n= [t-las,t] 如果 i 和 j 冲突,建边 i -> j + n 如果 i 和 j + n 冲突,建边 i -> j 如果 i + n 和 j 冲突,建边 i + n 阅读全文
posted @ 2012-10-01 10:40 'wind 阅读(206) 评论(0) 推荐(0)
摘要:题意:已知一个圆上顺时针放着 n 个点,这 n 个点中有m对顶点之间有连线,连线要么在园外要么在圆内,每个点最多连接一条边,问是否存在一种连接情况满足所有的 边都不相交。分析:将每条边看成两个点 i ,i+m 分别表示边在内部和在外部,如果两条边i,j的端点存在序号上的交叉,则这两对点之间的连线一个在外部一个在内部 即如果存在 i,则必存在 j+m ,如果存在 j ,则必存在 i+m, 如果存在 i+m,则必存在 j ,如果存在 j+m ,则必存在 i, 建图的时候连的边为 i -> j+m j -> i+m i+m -> j j+m -> i求出强连通分量并染色,判断 阅读全文
posted @ 2012-09-29 14:06 'wind 阅读(179) 评论(0) 推荐(0)
摘要:题意: 有 n 个变元,给出了 m 个他们中的一些元素的关系,问是否存在合法的取值方案。分析: 典型的2—SAT,在有冲突的取值方案之间连边, x 表是x取真,x+n表示x取假 建图:a and b ==1 , !a->a , !b -> ba and b ==0 , a->!b , b->!a a or b ==1 , !a->b , !b->a a or b ==0 , a->!a , b->!b a xor b ==1 , a->!b,!b->a,!a->b,b->!a a xor b ==0 , a->b,b 阅读全文
posted @ 2012-09-15 13:12 'wind 阅读(260) 评论(0) 推荐(0)
摘要:题意: 知道了一些集合的包含关系,问至少还要知道多少个包含关系才能证明这些集合是相互等价的。分析: 看出是强连通分量的模型就不难了。 最少加多少对关系使得每个集合等价,相当于在图中加入一些边,使得原图任意两个点互达即强连通, 找出这个边数即可。#include<stdio.h>#include<string.h>#define maxn 20002#define clr(x)memset(x,0,sizeof(x))struct node{ int to,next;}e[1000000];int tot;int head[maxn];void add(int s,int 阅读全文
posted @ 2012-09-12 23:07 'wind 阅读(206) 评论(0) 推荐(0)
摘要:题意:有 N 个奶牛,奶牛A可能认为B 优秀,奶牛B可能认为C优秀,这种关系具有单向传递性,即在此情况下,奶牛A认为奶牛C也是优秀的,但奶牛B不一定认为A优秀, 问可以找出有多少个奶牛可以被其他所有奶牛都认为是优秀的。分析:如果奶牛A认为奶牛B优秀,就连一条从B到A的边,求出强连通分量并染色缩点,最后计算入度为0 的强连通分量是否只有一个,如果是则输出该强连通分量内点的 个数,否则就不存在满足条件的奶牛。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))#define min(a, 阅读全文
posted @ 2012-08-16 21:52 'wind 阅读(209) 评论(0) 推荐(0)
摘要:题意: 国王有 N 个王子,一共有 N个女子,知道了每个王子喜欢的女子,和一组互不冲突的男女匹配,问每个王子可以娶那些女子且不影响其他所有的王子都可以娶到 自己喜欢的女子。分析: 如果某个王子喜欢某个女子,就连一条从该王子到该女子的边,如果某个女子某个王子可以匹配,就连一条从该女子到该王子的边。 如果一些王子和一些女子的同一个强连通分量里,则这些王子可以娶该强连通分量里的任意的女子。#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;#define maxn 40 阅读全文
posted @ 2012-08-16 10:02 'wind 阅读(157) 评论(0) 推荐(0)
摘要:题意: 知道了N 个学校,以及每个学校提供软件支持的学校编号,一个学校得到软件支持之后便可以支持他能支持的学校,问至少对多少学校提供软件支持可以使得 所有学校都得到软件支持,和至少在这些学校添加多少条边能使得任何一个学校得到软件支持后,其他所有学校都能得到软件支持。分析: 先求出所有的强连通分量并进行染色缩点,找出入度为 0 的强连通分量,其个数即为使所有学校得到支持所需要提供软件支持的最小数量, 而根节点与叶子节点 数量中的最大值即为最少添加的边数。#include<stdio.h>#include<string.h>#define clr(x)memset(x,0, 阅读全文
posted @ 2012-08-15 22:35 'wind 阅读(211) 评论(0) 推荐(0)
摘要:题意: 有一对 新人举办婚礼,邀请了n-1对夫妇,有一张很长的桌子,要求左右的夫妇都分别坐在桌子的两侧,且知道了 m 对 人有关系,要求新娘对面不能出现有关系的两个人。分析: 在 有关系的人之间连边,在所有夫妇之间连边,用奇数表示男的,偶数表示女的,用2-sat方法染色,最后输出不在新娘一边的人。#include<stdio.h>#include<string.h>#define op(x) ((x)=='h'?1:0)#define clr(x)memset(x,0,sizeof(x))#define min(a,b)(a)<(b)?(a):(b 阅读全文
posted @ 2012-08-04 23:56 'wind 阅读(228) 评论(0) 推荐(0)
摘要:题意: 给定一个无向图,图中存在一些桥,之后向图中加入Q条边,问每次加入这条边后图中剩下的桥的数量。分析: 首先对无向图求割边,并进行缩点,使之成为一棵树,这棵树上的所有边都是割边,之后对于每次询问,会连接树上的两个节点,如果这两个节点之间的边与这条边形成一个环,那么这些边就不再是割边,对于缩点后的树,先随意定出一个根,之后对每个节点记录他的父节点,以及他在这棵树中的深度,之后对于每次询问只要从叶子节点一直搜到他们的lca,把路径上的割边去掉。#include<stdio.h>#include<string.h>#include<stdlib.h>#defi 阅读全文
posted @ 2012-08-04 00:48 'wind 阅读(221) 评论(0) 推荐(0)
摘要:题意: 找出无向图的割点,并判断每个割点去掉后能形成多少个双连通分量。分析: 割点的定义: 在深搜树中,时间戳为 dfn[k] ,当 K 满足(1)(2)中一个时,k 为割点 (1) k 为深搜树的根,当且仅当 k 的儿子个数>=2 时 k 为割点;(2) k 为深搜树的中间节点(k 既不是根也不是叶),那么k 必然有父亲和儿子; 对于(1)是显然的,根结点k一旦有2个以上的分支,那么删除k必然出现森林; 对于(2)首先注意low[son]>= dfn[k]这个条件,意思就是“k的儿子son的辈分最高的祖先(暂且设其为w)的深度,比k的深度要深(或者等于k的深度,此 时k就是w), 阅读全文
posted @ 2012-07-17 15:52 'wind 阅读(254) 评论(0) 推荐(0)
摘要:题意: 一个有 N 个景点的岛,任意两个景点都有道路相连,当道路施工时,游客便不能在该道路上通行,问至少再增加几条道路可以使得在任一条道路维修的情况下,游客都能从岛上任意一个景点到达另一个景点。分析: 当原图中存在桥的时候,即原图不是双连通图的时候,目的就无法达到,所以这题的关键在于 需要增加几条边可以使得原图中不存在桥。 可以先找出原图中所有的边双连通分量,对其进行缩点,缩点具体做法是将 图中low值相同的节点看作一个点, 缩点后,原图可以看成是一颗树,而要使得一棵树变为一个双连通图,有一个定理: 增加的边数 = (树中总度数为1的节点数+1)/ 2转一大神分析:对于这种题,我们正常的做法是 阅读全文
posted @ 2012-07-16 15:00 'wind 阅读(253) 评论(0) 推荐(0)
摘要:题意: 给一个有向图,问该图是不是强连通图,且图中每条边仅属于一个环。分析: 如果一个节点已经在栈中,当该点被访问到即又出现了一条连向该点的横向边,且该点不是根节点,这条边 就是一条属于两个环的边。code:View Code View Code #include<stdio.h>#include<string.h>#define clr(x)memset(x,0,sizeof(x))const int maxn=20002;struct node{ int to; int next;}e[50005];int tot;int head[maxn];void add(i 阅读全文
posted @ 2012-07-15 22:04 'wind 阅读(196) 评论(0) 推荐(0)