![](https://img-blog.csdnimg.cn/20201014180756754.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
图论
文章平均质量分 67
logic_nut
这个作者很懒,什么都没留下…
展开
-
pku 1861 Network(并查集实现Kruskal)
Kruskal算法。先按length用qsort排序,再利用并查集来做。我一开始给并查集操作加上了路径压缩,但后来我把那段代码去掉后再提交,运行时间却基本没变化。 #include using namespace std;struct node{ int length; short first; short second;};short paren原创 2009-07-20 10:42:00 · 751 阅读 · 2 评论 -
pku 2983 Is the Information Reliable?(差分约束系统)
差分约束系统构图 A=B+x => A-B>=x && A-B A>=B+1判断负环因为只需要判断是否存在负环,所以无需添加超级源点。直接把所有节点的dist属性初始化为0。#include using namespace std;struct Edge{ int x,y,dist;}edges[200005];int edge_num,N,原创 2009-08-27 14:04:00 · 812 阅读 · 0 评论 -
pku 2186 Popular Cows(强连通分量)
强连通分量的一种求法:先深搜整个网络中的每个节点,记录每个节点访问结束的顺序(如代码中过的DFS1函数)。反转图中边的方向。按节点访问结束从后往前的顺序,深搜,每一棵深搜形成的树就是一个强连通分量(如代码中的DFS2函数)。 下面说明部分转自http://www.cppblog.com/RyanWang/archive/2009/02/26/74984.aspx,同时也参原创 2009-08-28 10:37:00 · 1172 阅读 · 1 评论 -
pku 2516 Minimum Cost(最小费用最大流)
赤裸裸的最小费用最大流。构建超级源点和超级汇点,源点出边的容量等于对应节点的储量,汇点入边的容量等于对应节点的需求量。 总结:本题因为用数组做队列时预留的空间不够,贡献了数次RE。#include using namespace std;#define MAXN 105#define MIN(x,y) (x<y?x:y)#define INF 2000005int原创 2009-08-28 13:07:00 · 1104 阅读 · 0 评论 -
pku 3352 Road Construction(割边,缩点)
无向图求割边:以任一节点为起点,深搜,记录每个节点第一次访问的时间DFn,同时记录当前节点不经过其父节点能够访问DFn值最小的节点low。假设a是b的父亲,如果low[b]题目:给定一个网络,求最少增加多少条边,可以使这个网络成为一个稳定的网络(网络中任意一个节点坏掉,整个网络仍然保持连通)。算法:找到割边,获得双连通分量。将同一双连通分量内的节点缩成一个节点,则整个网络变成了一棵树。通过原创 2009-08-28 19:31:00 · 835 阅读 · 2 评论 -
求网络的最小割
求网络的最小割最大流最小割定理,首先求得最大流。然后残留网络中,从源点出发深度优先遍历,所有被遍历到的点构成点集S,剩余的点构成点集T。则edge即是最小割的割边集。转载 2009-08-29 11:28:00 · 750 阅读 · 0 评论 -
pku 3308 Paratroopers(带权二分图最小点覆盖)
把伞兵看成边,行列看成节点,转化为了带权二分图最小点覆盖。加入超级源点和超级汇点,源点和所有行节点相连,所有列节点和汇点相连,如果a行b列有敌人,则把节点a和节点b相连。则问题又可以转化求最小割。现在求源点和汇点之间的最小割。因为对任一敌人,必然有source-->a-->b-->sink, 割的性质是"不存在一条从source到sink的路径", 故路径上的三条边, , 中至少有一条边在原创 2009-08-29 13:42:00 · 1744 阅读 · 1 评论 -
pku 1125 Stockbroker Grapevine(Floyd-Warshall)
Floyd-Warshall算法计算各点对之间的最短路径权值,最后把所有起始点遍历一下,选出满足要求的点。 // pku 1125.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include using namespace std;#define rm(原创 2009-07-13 17:13:00 · 581 阅读 · 0 评论 -
google code jam PermRLE(最短哈密顿通路)
字符串压缩,转换成求哈密顿通路。问题ProblemYouve invented a slight modification of the run-length encoding (RLE) compression algorithm, called PermRLE.To compress a string, this algorithm chooses some permutat原创 2009-09-17 17:42:00 · 1395 阅读 · 0 评论 -
pku 1635 Subway tree systems(树的同构,最小表示)
树的同构的判断,先用深搜得到以某个节点为起点的01表示,0表示往远离中心的节点走,1表示往靠近中心的节点走。用了两种方法做。1.把树去除根节点后,可以分成数棵子树。每个子树对应一个01串,然后用字符的比较函数排列这些01串。递归调用,得到树的一种最小表示。下面的代码因为反复使用string,速度很慢很慢。#include #include #include #inclu原创 2009-09-21 09:34:00 · 1518 阅读 · 3 评论 -
pku 3140 Contestants Division(树的划分)
题目:给定一棵树,每个节点有一个权值。任意去掉一条边会形成两颗子树,每颗子树有一个权值和,求二者相差的最小值。分析:先求出所有节点权值总和,然后以任意一个节点为根节点,深搜,求每个节点的(本身及其子节点)权值和,直接和sum比较就可以得到去除该节点和父节点之间的边时的答案。教训:又一次栽倒在vector上,因为是多数据,每次使用vector之前都需要clear。因为忘了这个WA了数次。原创 2009-09-25 23:15:00 · 934 阅读 · 0 评论 -
pku 1966 Cable TV Network(求无向图的点连通度)
求无向图的点连通度。解决办法:拆点,转换为求边连通度。通常情况下怎么求边连通度?给每条边赋权值1,任意选择源点,枚举汇点,依次求最小割。那么求无向图的点连通度该怎么建图?拆点,对于原始无向图中的边(a,b),在新图中有(a+N,b)=(b+N,a)=INF。同时对i任意选择起点,枚举汇点,求(start+N,end)的最大流,即最小割。需要注意的是,当最小割的值大于等于N,原创 2009-10-29 20:34:00 · 1349 阅读 · 0 评论 -
pku 3625 Building Roads(最小生成树)
简单题,直接上kruskal,可惜花了700+ms。#include "math.h"#include "float.h"#include #include using namespace std;double pos[1000][2],ans;int N,M;struct node{ int s,t; double dist;}nodes[1000原创 2010-02-08 13:57:00 · 690 阅读 · 0 评论 -
pku 2395 Out of Hay(最小的最大边)
已知一个连通的图。从原图中选出一些边,确保图保持连通性。要求在选出的边中,最大边的值要尽量小。根据XX 定理,要求的值即为该图的最小生成树的最大边。用kruskal或prim均可解决。不过今天,我们换一下做法。一,用bellman-ford变形来做,其中用到了bellman-ford的优化版本,基于栈的spfa#include using namespace原创 2010-04-09 22:39:00 · 789 阅读 · 0 评论 -
pku 1860 Currency Exchange(Bellman-Ford )
还是币种交换问题,只是这里换汇的时候需要支付手续费。转化为最短路径问题,因为有负权路径,用Bellman-Ford 算法。当路径存在负环时就可以无限制刷钱,所以最终肯定是赚的。//descrption below is added on August 31,2011We can earn money as long as the negative-circle exists原创 2009-07-31 12:05:00 · 1332 阅读 · 3 评论 -
pku 3041 Asteroids(最小点覆盖,最大二分匹配)
每一个asteroid都可以从行或列的角度来击碎,因此把asteroid当成边,row和column当成点,可以构造出一个二分图。然后利用二分图中最小点覆盖=最大二分匹配 来解答。#include using namespace std; bool map[505][505]; bool visited[505]; int pre[505]; int N原创 2009-08-07 19:57:00 · 668 阅读 · 0 评论 -
poj 3204 Ikki's Story I - Road Reconstruction (最大流的应用)
题目:对于一个有向图,提高一条边的容量,可能可以增加该图的最大流。对给定的图,问存在多少条这样的边。解法:先求最大流,把边填充好,得到残余图。在残余图中,从s出发DFS,把所有能到达的点标记。同样从t出发DFS,把所有能到达的点标记,不过要注意这里边是反向的。最后枚举边,如果原创 2011-09-26 09:21:57 · 754 阅读 · 0 评论 -
pku 1325(二分匹配模版)
最小点覆盖---最大二分匹配。题目中有个容易被忽视的地方,两台机器的初始状态都是mode 0。而处理的方法也是很有意思,就是直接忽略那些和左右0节点相连的边。#includeusing namespace std;bool map[105][105];bool vi原创 2011-09-26 01:27:19 · 568 阅读 · 0 评论 -
pku 1201 Intervals(差分约束系统)
线性规划和图论最短路径的完美转换。设S(i)表示从0到i-1这i个数中,有多少个数是是被选中的。对输入 a b c,有S(b+1)-S(a)>=c。(1)同时有0根据这三个不等式构建图。 通常在构图完成后,我们需要求两个节点之间的最短距离。构图完成后怎么求最短路?1.把所有的节点的初始dist都设置为0,用bellman-ford跑一遍。2.想要用spfa的话,就需要把所有原创 2009-08-23 12:09:00 · 1230 阅读 · 0 评论 -
如何寻找欧拉回路、欧拉通路(套圈法)
传说中的套圈法。算法思想的朴素表达对于欧拉图,从一个节点出发,随便往下走(走过之后需要标记一下,下次就不要来了),必然也在这个节点终止(因为除了起始节点,其他节点的度数都是偶数,只要能进去就能出来)。这样就构成了一个圈,但因为是随便走的,所以可能会有些边还没走过就回来了。我们就从终止节点逆着往前查找,直到找到第一个分叉路口,然后从这个节点出发继续上面的步骤,肯定也是可以找到一条回到这个点的原创 2009-08-23 07:01:00 · 14733 阅读 · 2 评论 -
pku 2337 Catenyms(寻找欧拉通路)
以字母为节点,字符串为边,寻找欧拉回路。一开始不会,用的深搜回溯找的路径。后来问了lvyun,才知道有个很好用的套圈法,每条边只要走一次O(e)的效率。关于套圈法,可以参看http://blog.csdn.net/logic_nut/archive/2009/08/23/4474307.aspx深搜回溯#include using namespace std;int deg原创 2009-08-22 17:44:00 · 3306 阅读 · 2 评论 -
pku 2240 Arbitrage(floyd)
题意:给定各个币种间兑换的汇率,给你一定的起始资金,是否可以通过兑换来增值,要求最后必须兑换回起始的币种。 因为要测试每个币种是否可以增值,所以首先想到的是floyd。每个节点代表一币种,边存储币种之间的汇率。可套用floyd的模板,只需要稍微修改下边的松弛方式。 后来发现其实可以增加一个超级源点和所有节点相连,然后用bellman-ford找环。 #include usi原创 2009-08-02 19:36:00 · 620 阅读 · 1 评论 -
pku 1258 Agri-Net(标准prim)
这是O(v^2)的实现,以后就拿这个当模板了。#include using namespace std;int map[100][100];//存储边权值bool inTree[100];int min_length[100];//非Tree结点和Tree中的结点间的min_distance int prim(int n){ int sum_length=0;原创 2009-08-03 08:13:00 · 478 阅读 · 0 评论 -
pku 1094 Sorting It All Out(拓扑排序)
拓扑排序的实现,即是为每个节点保存一个degree(入度)的值,当某个节点入度为0,就保存起来(队列,栈,临时寻找)。取出入度为0的结点进行扩展,和该结点相邻的结点入度减一,存储其中入度为0的结点。循环至终。若最后仍存在入度大于0的结点,即说明有环。这题差不多是拓扑排序的直接应用,只不过这里要求所有节点之间的关系必须是“严格”的。因此当无法严格确定各个节点之间的关系或网络存在环需要返回恰当的值原创 2009-08-02 19:41:00 · 606 阅读 · 0 评论 -
网络最大流和最小费用流
这段时间复习了下网络流模型,感觉比以前的理解有了长足进展,虽然我知道这东西难就难在建模上,而它的算法本身其实难度不大,但我还是决定说一些我的理解,毕竟理解了本质的东西运用起来才会更灵活。最大流的求解一般有两类算法(用费用流附带求出的不列入考虑范围),就是增广路(FF)系列和预流推进(PF)系列。在很多地方都看到推荐使用后者,因为效率更高,但其实不然,今天我这篇文章就是要重点介绍前者,相信大家看转载 2009-08-04 10:21:00 · 2279 阅读 · 0 评论 -
pku 1459 Power Network(最大流)
题目有点难懂,其实是无源无汇最大流。将源点和所有station相连,容量限制为生产量;将所有consumer和汇点相连,容量限制为消耗量。输入控制有点麻烦,通过在scanf()的格式控制串中加空格吃掉输入中多余的空格。#include using namespace std;#define MAXN 105#define MIN(x,y) (x<y?x:y)#define IN原创 2009-08-03 16:27:00 · 1062 阅读 · 1 评论 -
pku 3259 Wormholes(bellman-ford)
题目的意思就是要判断一下整个路网中有没有负权回路,而bellman-ford算法正好有这样的作用。因为bellman-ford算法只能扫描到那些和起始节点相连通的节点,这里我们给原路网增加一个超级起始节点s,s和其他所有节点都连通。 题目描述中有a bidirectional path between S and E,这里a bidirectional path 是双向路径的意思。原创 2009-07-31 13:44:00 · 728 阅读 · 0 评论 -
pku 2253 Frogger(Dijkstra+heap)
WA了无数次。改变量类型,改输出控制,检查数组初始化。还是WA。最后发现,原来还是queue没有初始化。多case的情况就得注意变量初始化呀。#include "math.h"#include #include #define Distance(x,y,x2,y2) ((x-x2)*(x-x2)+(y-y2)*(y-y2))#define Max(x,y) ((x)>(原创 2009-07-31 23:20:00 · 664 阅读 · 0 评论 -
pku 2485 Highways(prim)
The Flatopian government wants to minimize the length of the longest highway to be built. However, they want to guarantee that every town is highway-reachable from every other town.给定各点之间的权值,选择边构成一个原创 2009-08-03 00:15:00 · 431 阅读 · 0 评论 -
pku 2195 Going Home(最小费用最大流)
最大流算法的一种实现就是不断寻找增广路径,一般推荐用BFS。最小费用最大流算法其实就是最大流算法的增强版,限制了路径搜索算法必须为最短路径算法,其中路径的权值即是费用。算法本身不难,难在构图。通常需要构建超级汇点和超级源点,还有就是逆向路径的权值要设成正向路径权值的相反数,这点很关键。#include #include using namespace std;#define A原创 2009-08-06 18:54:00 · 1073 阅读 · 1 评论 -
二分图最大匹配问题匈牙利算法
研究了几个小时,终于明白了。说穿了,就是你从二分图中找出一条路径来,让路径的起点和终点都是还没有匹配过的点,并且路径经过的连线是一条没被匹配、一条已经匹配过,再下一条又没匹配这样交替地出现。找到这样的路径后,显然路径里没被匹配的连线比已经匹配了的连线多一条,于是修改匹配图,把路径里所有匹配过的连线去掉匹配关系,把没有匹配的连线变成匹配的,这样匹配数就比原来多1个。不断执行上述操作,直到找不到这样的原创 2009-08-07 00:33:00 · 609 阅读 · 0 评论 -
pku 1469 COURSES(二分匹配,匈牙利算法)
题目意思没怎么看明白,输出的时候参考了下别人的代码。主要是练习下二分匹配里面的匈牙利算法。#include using namespace std;bool map[105][305];//存储left和right两侧的对应关系,有边相连则为truebool visited[305];//right侧的节点是否已经访问int pre[305];//right侧节点对应的left原创 2009-08-07 09:31:00 · 803 阅读 · 1 评论 -
最小路径覆盖
在一个PXP的有向图中, 路径覆盖 就是在图中找一些路经,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,那么恰好可以经过图中的每个顶点一次且仅一次);如果不考虑图中存在回路,那么每每条路径就是一个弱连通子集. 由上面可以得出: 1.一个单独的顶点是一条路径; 2.如果存在一路径p1,p2,......pk,其转载 2009-08-07 10:23:00 · 690 阅读 · 0 评论 -
最小点覆盖
无向图中,最少需要多少个点可以覆盖所有的边。一条边被覆盖是指至少有一个和它相邻的点被选中。特别的,如果该图是二分图,有 最小点覆盖=最大二分匹配。原创 2009-08-07 11:18:00 · 2185 阅读 · 0 评论 -
欧拉图
昨天做题用到了欧拉图,本来刚看到这个名词我是不知道什么是欧拉图的,wiki了一下发现原来欧拉图就是小学奥数做腻了的"一笔画"问题... 图论起源于18世纪,1736年瑞士数学家欧拉(Eular)发表了图论的第一篇论文:哥尼斯堡七桥问题"。在当时的哥尼斯堡城有一条横贯全市的普雷格尔河,河中的两个岛与两岸用七座桥联结起来,见图(1)。当时那里的居民热衷于一个难题:游人怎样不重复地走遍七转载 2009-08-09 12:01:00 · 2493 阅读 · 0 评论 -
pku 2513 Colored Sticks(Trie树,并查集,欧拉通路)
trie树,用来形成char[]与int之间的对应。(hash也不错)颜色是节点,stick是边。possible的充要条件是图中存在欧拉通路。存在欧拉通路的充要条件是:1 图是连通的(并查集判断)。2 图中节点的度,全部为偶数或者2个节点的度为奇数。#include using namespace std;#define NODE_MAX 1000005#defi原创 2009-08-09 13:23:00 · 841 阅读 · 1 评论 -
差分约束系统
摘自百度百科,很短很精炼 如果一个系统由n个变量和m个约束条件组成,其中每个约束条件形如xj-xi<=bk(i,j∈[1,n],k∈[1,m]),则称其为差分约束系统(system of difference constraints)。亦即,差分约束系统是求解关于一组变量的特殊不等式组的方法。 求解差分约束系统,可以转化成图论的单源最长路径问题。 观察xj-xi<=bk,会转载 2009-08-23 09:14:00 · 738 阅读 · 1 评论 -
pku 1273 Drainage Ditches( Edmond-Karp最大流模板)
经过证明,若每次用最短的增广路径进行增广,则最多只需要O(VE)次增广。(如何证明?)用BFS求最短增广路径,每次增广复杂度是O(E)。因此,总时间复杂度为O(VE2)。该算法名叫Edmond-Karp算法。#include using namespace std;#define MAXN 205#define INF 2110000000#define MIN(x,y) (x原创 2009-08-03 12:12:00 · 1447 阅读 · 0 评论