随笔分类 -  图论

摘要:题意: 给n个黑点和n个白点的坐标,然后连n条线段连接黑点和白点,使得所有线段不相交,求匹配方案。解法: 白书上的例题,建图思路蛮好的。 二分图,黑点和白点在两个集合里。然后求最小匹配,这样的结果肯定保证线段不相交。为什么呢? 因为不存在三点共线,所以对于两条线段来说,如果他们相交了,我们可以交换一下匹配的点使得四个点构成两条不相交的线,这样结果肯定要变小,画个图就知道了。p.s.貌似卡精度??被卡爆了。。。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include< 阅读全文
posted @ 2013-02-23 22:51 silver__bullet 阅读(491) 评论(0) 推荐(0)
摘要:题意: 给定n*n的矩阵,每个格子有个值s[i][j],现在要求对每行和每列各分配一个值,r[i],c[i]使得对所有的格子都有s[i][j]<=r[i]+c[j]成立,并且sum{r[i]}+sum{c[i]}尽量小。解法: 最近在做各种匹配,看到那个不等式,很容易联想到KM算法中那个lx[i]+ly[j]>=w[i][j],在KM结束之后,所有顶标之和是最小的。 想一下KM的思想,就是通过修改顶标的值来使得尽量多的边满足lx[i]+ly[j]==w[i][j],因为这样的边才会进入相等子图。而在算法结束后,所有的点都已经完成了匹配,也就是对于每对匹配点i,j,lx[i]+ly[ 阅读全文
posted @ 2013-02-22 12:07 silver__bullet 阅读(330) 评论(0) 推荐(0)
摘要:解法: 二分图的模型显而易见,而且对于一个不含孤立点的二分图,最小点覆盖数=最大匹配数。问题要求输出一个最小点覆盖集,我们可以在求出最大匹配之后,以未覆盖的x点进行标记,沿着未覆盖->覆盖->未覆盖->覆盖...的路径标记,最后x中未标记的和y中标记的点构成最小点覆盖集。具体的讲解可以看这个p.s.代码写的太丑了~~~~(>_<)~~~~ 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 #define N 1 阅读全文
posted @ 2013-02-21 21:58 silver__bullet 阅读(718) 评论(0) 推荐(0)
摘要:题意: 给定一个有向图,把图分成一些环,要求每个点只属于一个环,求满足条件的环所有边权和的最小值。解法: 对于满足条件的环,每个点的入度和出度均为1,我们可以把每个点拆成入点和出点,那么也就是说一个入点对应一个出点,反之亦然,那么这个问题就变成了一个二分图匹配问题,因为要取最小值,我们可以把每条边的权值取相反数,然后求一次最优匹配,对求得的结果再取相反数即为答案。 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define N 110 5 using namespace std 阅读全文
posted @ 2013-02-19 14:22 silver__bullet 阅读(468) 评论(0) 推荐(0)
摘要:题意:有N头牛,F种食物,D种饮料,每头牛有自己喜欢的食物和饮料,每种食物/饮料只能被一头牛享用,每头牛只能享用一种饮料和一种食物,求最后能有几头牛享用到自己喜欢的食物或饮料。解法:很容易想到建图方法,食物放左边,饮料放右边,牛放中间,然后按照给定的关系连边,但这里需要对牛拆点,如果不拆的话,比如有这样的两条链,s->食物1->牛1->饮料1->t,s->食物2->牛1->饮料2->t,这两条路都会被增广,从而出现错误,因为建图的时候并没有限制“每头牛只能享用一种饮料和一种食物”这个条件,拆点之后就有了限制。。。 1 #include<cs 阅读全文
posted @ 2013-01-23 17:54 silver__bullet 阅读(209) 评论(0) 推荐(0)
摘要:题意:求从顶点1走到n再走回1的最短路径,每条边只能走一次。解法:最小费用最大流,另设源点汇点,从源点到1连边,从n到汇点连边,这两条边都是容量为2,费用为0,表示要走两条包含源点(或汇点)的边,因为一去一回走的边不一样。。其余的边正常建就行,费用就是路径长度。。 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 #define N 1010 6 using namespace std; 7 const int inf=1<< 阅读全文
posted @ 2013-01-20 16:16 silver__bullet 阅读(197) 评论(0) 推荐(0)
摘要:题意:给定一个n节点m条边的无向图,定义c为每对顶点的最短路之和,要求删掉一条边重新求一个c值c',求出c'最大值.解法:dijkstra+堆优化,最短路径树. 首先可以通过dijkstra求出单源最短路,对于删边的操作,如果我们枚举每条边的时候都求一次最短路肯定是超时的. 对于一个源点确定的最短路径树,如果我们删掉的边不在这个最短路径树上,那么就不需要重新计算最短路. 根据这个性质,我们只需要记录下每个源点构成的最短路径树上都有哪条边,然后在枚举边的时候判断是否需要重新计算最短路 1 #include<cstdio> 2 #include<queue> 阅读全文
posted @ 2012-11-28 11:23 silver__bullet 阅读(501) 评论(0) 推荐(0)
摘要:题意:...解法:求最大流并给出一种流量分配方案. 建图过程,每个机器有入口和出口,所以要拆点. 如果不拆点的话,下面的样例可以cha掉这个解法 2 4 10 0 0 0 1 10 0 0 0 0 10 0 1 1 1 10 0 1 1 1 至于输出一种可行方案,我们可以想一下dinic算法的执行流程,每次增广的过程都发生在dfs的时候,所以在回退增广的时候我们可以记录下这条边是否被增广... 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm 阅读全文
posted @ 2012-11-24 16:42 silver__bullet 阅读(153) 评论(0) 推荐(0)
摘要:题意:....解法:很容易发现这是个匹配问题,如果直接建图的话,点的数量会达到10^5..需要进行压缩,我们发现m最大只有10个,那么表示人数的那些点可以按照和星球相连的情况进行压缩....压缩之后建图求最大流即可... 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #define N 1500 6 using namespace std; 7 const int inf=(1<<30); 8 struct Edg 阅读全文
posted @ 2012-11-21 23:11 silver__bullet 阅读(223) 评论(0) 推荐(0)
摘要:题意:混合图求欧拉回路。解法:对于欧拉图,所有顶点入度和出度之差均为偶数。 建图思路:1.首先为无向边随意定一个方向,统计每个点入度出度; 2.另设源点汇点,对于出度>入度的点,与源点连边,正向边容量为(out-in)/2,对于入度>出度的点,与汇点连边,正向边容量为(in-out)/2; 3.对于除了源点汇点之外的点,有向边舍弃,无向边按照先前指定的方向建边,容量为1. 整个图建好之后,流经每个顶点的容量可以理解成把这个点的入(出)边变成出(入)边的数量。。。 如果是满流就表示所有的点最后都能使得入度==出度。。 1 #include<iostream> 2... 阅读全文
posted @ 2012-11-15 23:57 silver__bullet 阅读(147) 评论(0) 推荐(0)