随笔分类 -  图论

摘要:图论构造类问题题意:输入n个点,要求你连接一些边,使其变为无向图,并且,在图中任选3个点,这3个点的度都不会完全相等构造方法是对于奇数个点,第n/2+1个点不要连线,将点集分为相等的两部分,1到n/2为一部分,n/2+2到n为一部分,从第一部分开始连线,都指向第二部分,1号点连n/2条,2号点连n/2-1条,3号点连n/2-2条………………n/2号点连1条对于偶数个点是一样的,刚好能将点分为两个部分,两个部分的连线方法一样(这构造太巧妙了,很容易就能看到不会有3个点的度相同)#include <iostream>#include <cstdio>#include < 阅读全文
posted @ 2013-06-12 17:50 Titanium 阅读(204) 评论(0) 推荐(0)
摘要:欧拉回路题意:给一个有向图,判断是否是欧拉回路,并且输出路径, 要求字典序最小。其中输出时这个给的,x y z,x和y是点的编号(点数最多44),z是边的编号(这边是有编号的,边数最大1995),其中输出路径不是输出点而是输出边的编号,所以字典序最小是指边的字典序最小。每组数据以0 0 结束。其中每组数组的第一行,两个点x,y,选较小的那个作为起点这题,图是保证连通的,所以不需要判断连通,所以判断是不是欧拉图,只需要看每个点的度是否都为偶数,不是的话则不存在欧拉回路,是的话就存在欧拉回路输出字典序最小的路径,环一个建图方法即可e[k][0] , e[k][1]表示第k条边的两个顶点我们用递归的 阅读全文
posted @ 2013-06-07 18:20 Titanium 阅读(269) 评论(0) 推荐(0)
摘要:连通分量+LCA题意:一个无向图可以有重边,下面q个操作,每次在两个点间连接一条有向边,每次连接后整个无向图还剩下多少桥(注意是要考虑之前连了的边,每次回答是在上一次的基础之上)首先运行一次tarjan,求出桥和缩点,那么远无向图将缩点为一棵树,树边正好是原来的桥。每次连接两点,看看这两点是不是在同一个缩点内,如果是,那么缩点后的树没任何变化,如果两点属于不同的缩点,那么连接起来,然后找这两个缩点的LCA,,因为从点u到LCA再到点v再到点u,将形成环,里面的树边都会变成不是桥。计数的时候注意,有些树边可能之前已经被标记了,这次再经过不能再标记首先按思路写了个代码,跑了2s多,因为显式建树了。 阅读全文
posted @ 2013-05-29 15:31 Titanium 阅读(2593) 评论(3) 推荐(0)
摘要:强连通分量题意:一个n行m列的矩阵图,上面有3种点,可能是数字x(0<=x<=9),表示这里有多少个矿石,#表示不能走到这点,*表示传送点,对应一个目标点,可以瞬间传送到目标点。你从(0,0)左上角处出发,行走的方向只能是向左或者向下,要求你走到某个地方(不一定是右下角),让你得到的矿石最多。一个地方的矿石只能采集一次,下次再去到那个点是没有矿石的。注意几点,传送点可能将你传送到#这种点,那么相当于这个传送点是多余的等于没用,另外在传送点可以选择传送或者不传送继续走。分析:由于传送点的存在,可能使这个有向图构成环,进而可能产生强连通分量,所以先建图,进行一次强连通分量缩点,为什么缩 阅读全文
posted @ 2013-05-24 09:29 Titanium 阅读(400) 评论(0) 推荐(0)
摘要:强连通分量题意:给一个有向图,对于图中任意两个点u,v,如果从u能到v,或者,v能到u,则这对顶点是可行的,如果图中任意一对顶点都是可行的,可以输出Yes,否则输出No这个的话,就不是裸的强连通分量了。思考一下,对于一个有向图而言,里面的强连通分量肯定满足题目的条件,因为强连通分量内是u可到v,而且,v可到u,所以我们第一步工作就是强连通分量缩点,变为一个DAG。对于这个DAG里面的任意两个点U,V,如果满足题目的条件,那么点U,V里面包含的原图的点也肯定是满足的所以问题转化为怎么判断这个DAG是满足题目条件呢?其实判断很简单,就是看这个DAG里面有多少个点的入度为0,多少个点出度为0如果DA 阅读全文
posted @ 2013-05-23 11:15 Titanium 阅读(993) 评论(1) 推荐(0)
摘要:双连通分量题意:给一个无向图,要求毁掉两个点,使图变得不连通,图一开始是连通的因为要毁掉两个点,就不是简单的求割点,再看看数据范围,点数为1000,边数为10000,Tarjan的时间复杂度为O(E),如果用枚举法,先枚举要毁掉的第一个点,再用Tarjan进行处理来找割点会不会超时呢?答案是不会,时间为O(v*E),刚好是千万级别,不超做法:先枚举要删除的第1个点,在原图中删除它,看看删除它后整个图的变化 1.整个图变得不连通了(即这个点本身是割点),但是还没完要分类讨论一下 (1).整个图变为两部分,但是两部分刚好都是一个点,那么这两个点再毁掉哪个点都好,图的连通分支数都不会增加... 阅读全文
posted @ 2013-05-22 08:32 Titanium 阅读(576) 评论(0) 推荐(0)
摘要:双连通分量题意:输入比较恶心,没有说有多少点,点的标号也不一定,只给出了边。一个无向图,但是保证是连通的(所以只要做一次dfs),问那些电脑坏了,会使整个网络断开分成几个部分。其实很直白就是求割点。输出就是,如果整个图为点双连通分量,则输出No SPF nodes , 否则按标号从小到大输出每个割点,并且输出,去掉该点后,整个图会分成几个部分这题算是个模板题,但是WA了,是因为模板有问题,也是自己对双连通分量的理解有问题,改了一下模板过了,发现自己之前想的东西有点复杂,把模板一些细节处搞错了,但是之前做了几道题都是1Y的,这个题目错了,感觉错得很值。对于什么是割点,在这里不说了,百度很多,对照 阅读全文
posted @ 2013-05-21 22:35 Titanium 阅读(597) 评论(0) 推荐(0)
摘要:双连通分量题意:给一个无向图。如果至少有两个环共用了一些边,那么这些边被认为是“冲突边”。如果一些边不在任何一个环中,这些边被认为是“多余边”。你要找出这个图中有多少“多余边”和“冲突边”然后输出条数。另外这图不一定是连通的1.“多余边”不在任何一个环中,那么多余边一定是桥,所以统计这个无向图中有多少桥即可2.“冲突边”有多少,这个有点费劲,但是不难想到。如果一个环比较特殊,n个点刚好n条边,例如(1,2)(2,3)(1,3)这种环,这个环内,一条“冲突边”都没有,但是如果一个环内的边数大于点数,那么这个环内所有边都是“冲突边”(真可惜,因为有多出来的那些边后,相当于把最外面的大环分割成了内部 阅读全文
posted @ 2013-05-19 23:25 Titanium 阅读(1135) 评论(0) 推荐(1)
摘要:双连通分量边双连通分量+DP (其实不用DP,直接建树+遍历一次就能计算出全部的DP值)题意无向图连通,所以只要从一个点运行一次dfs即可,在运行dfs过程中保存下所有的桥并且计算出所有的边双连通分量。在tarjan之后对原图进行缩点,缩点后就能得到一棵,树边刚好就是全部的桥。缩点后每个大点都有一个权值,权值等于 = 属于该连通分量的每个小点的权值和。因此保存下全部桥是为了方便建树。建树之后对树进行一次遍历(很多人说是DP,其实不算是DP,只是简单的遍历而已)。遍历过程要计算每个节点的dp值,dp[i] = 以点i为节点的子树的所有节点的权值和因此每计算完一个节点的dp值后,就可以看看切断这条 阅读全文
posted @ 2013-05-19 17:32 Titanium 阅读(265) 评论(0) 推荐(0)
摘要:双连通分量题意:给一个无向图,问要添加多少条边形成边双连通分量。注意图一开始是连通的,所以只要从一个点开始dfs一次就行了,另外这图有重边,(1,2)(2,1)这样,则1,2就形成了一个边双连通分量。之前写的求边双连通分量的代码不能处理重边,但是要修改过来其实挺简单的。重边无非是遇到一个问题,从u走到v,按一般的做法,是不能从v回到u的,即不能马上就回到它父亲节点去(其实指的是不能重复走这条边,这条边虽然是无向边但是只能走一次),但是有了重边后,是可以马上回到它父亲处的,只不过走的是另一条边。所以我们可以标记哪些边用过了,每条边只能用一次,用过一次后不能再用。而且别忘了,建图的时候,无向边是分 阅读全文
posted @ 2013-05-19 17:25 Titanium 阅读(274) 评论(0) 推荐(0)
摘要:双连通分量题意:一个无向图要添加多少条边才能使其变为边双连通分量,和 poj 3352 Road Construction 几乎一样的题目,不同的是,poj这题,原图是保证连通的,这题是不连通的,过程完全一样,只是最后计算答案的公式不同.所以题目分析就不写了,直接看poj那题吧,其实这题也是模板题,懂双连通分量的知识的话,并不需要看分析poj那题,缩点后不会出现孤立点,因为整个图连通的,所以只要找到缩点后的叶子个数就可以了,所以是(leaf+1)/2对于这题,因为图不连通,可能出现缩点后的孤立点。首先看缩点后的图,可能是一块一块的,对于点数超过1的块,和poj那题是一样的,只要找到叶子,所以没 阅读全文
posted @ 2013-05-18 23:04 Titanium 阅读(826) 评论(0) 推荐(0)
摘要:推荐技术公众号:不爱睡觉的大猪 双连通分量 题意:比较裸的题意,就是给一个无向图,问添加多少条边后能使整个图变成双连通分量 分析:建议先学了双连通分量的相关知识,因为这题是算是个模板题(我自己写了模板,过了这题,但是还没有充分测试),如果没学好相关知识即便这个模板题也不好懂 双连通分量分为【点双连通 阅读全文
posted @ 2013-05-18 19:41 Titanium 阅读(2000) 评论(6) 推荐(1)
摘要:继续复习二分图题意:比较裸的二分图,输入n,表示n个不同的课程,下面n行,每行首先是m,表示后面跟着m对信息,每对信息为(p,q),表示在星期p的第q节上这节课,(一周7天,一天12节课)。问你怎么匹配,可以让这个人一周上最多的课。建立二分图,X为时间,[0,83],Y为课程,[0,n-1],然后有向边Y--->X,进行匈牙利一次即可#include <cstdio>#include <cstring>#define N 410#define M 50500int n,tot;int match[N];int head[N];struct edge{ int u, 阅读全文
posted @ 2013-05-10 20:55 Titanium 阅读(270) 评论(0) 推荐(0)
摘要:/*题意:给一个有向图,问有多少个点,是其他点都可以到达的其他点都可以到达该点,那么将图转置,就变为该点可以到达其他所有的点要找这样的点方法有很多,仿照Floyd的DP方法就是最容易写,但是点太多达到10000,会超时这里用SCC来做将转置后的图进行缩点,得到一个DAG,这个DAG每个大点内的小点(即原来的点)都是相互可达,关键是看这些大点能不能去到其他大点,如果一个大点能去到其他所有的大点,那么里面的小点也可以所以就是要找,有多少个大点,可以去到所有其他的大点,可知这样的大点,最多1个!!,而且是入度为0的点(这个不难理解,可以思考一下)找到了这个大点,那么里面包含的小点就都是可以的,所以扫 阅读全文
posted @ 2013-05-10 12:08 Titanium 阅读(223) 评论(0) 推荐(0)
摘要:强连通分量 + 最短路题意:城市间通信,给出n,n个城市,m,m条边,分别是端点和权,如果两个城市属于同一个国家,那么他们的通信时间为0,否则则按边权算一次的通信时间。两个城市被认为在一个国家,是从A能到B,从B也能到A。下面给出K个查询,能从u到v传递信息,需要多少时间,如果从u无法传递到v,输出那个长长的英文句子其实就是一个最短路,但是最短路的边权有讲究,虽然给出了u,v,w,但是u和v可能是同一个国家的,那么w应该是0而不是原来的值,所以要怎么判断u和v是不是在同一个国家,也就是他们可以互达,很明显不能查询一次判断一次,而是应该先搞出强连通分量,属于同一个强连通分量的两点间的边权为0这题 阅读全文
posted @ 2013-05-09 22:27 Titanium 阅读(312) 评论(0) 推荐(0)
摘要:强连通分量 缩点题意:这个题意比较难懂,题意读懂了,转化过来也不容易输入n,表示n个学校(1到n编号),下面n行,分别是对应每个学校的信息。每个学校可以给其他学校共享一些软件接而共享下去,要让所有学校用上软件,需要多少个学校带头共享软件;另外要让每个学校共享的软件都能被其他所有学校用上,那么要在原来的共享计划中,另外加入那些具体的共享呢(例如原来A学校不向B学校共享的,为了达到目的,A学校需要向B学校共享,因而增加了1)首先建立有向图,A向B共享软件,则有向边A--->B所有第1个问题,问的就是要多少次才能遍历完整个有向图,因为有这么多的学校带头共享软件了,沿着路径延伸,可以到达他们子树 阅读全文
posted @ 2013-05-09 20:59 Titanium 阅读(234) 评论(0) 推荐(0)
摘要:最短路题意:比较懒有点难描述,所以不说了,看Hint可以看懂的本题的巧妙之处是其实无论怎么走,从起点(固定的)走到任何一个点,到达那个点的时候速度都是确定的因为 速度为spa ,a--->b---->c , b点速度为 spb = spa * 2^(ha-hb) , c点速度为 spc = spb * 2^(hb - hc)式子一合并,就是 spc = spa * 2^(ha - hc) ,可见从点a走到点c,无论中间经过什么点,最后计算速度,之和点a和点c的高度差有关,当然和点a的速度也有关而起点是固定的(1,1),而起始速度是知道的,那么从点(1,1)走到任何一个点时的速度也就 阅读全文
posted @ 2013-05-06 22:37 Titanium 阅读(507) 评论(0) 推荐(0)
摘要:最短路题意:给n个点从1到n标号,下面一行是每个点的权,另外给出m条边,下面是每条边的信息,两个端点+权值,边是无向边。你的任务是选出一些边,使这个图变成一棵树。这棵树的花费是这样算的,1号固定为树根,树中每个双亲节点下面的边都有个单价(即边权),然后单价乘上这条边的下面所有的子孙后代的点权和(看sample2,只要除掉边 1 5 9 按照这个方法就能算出1210)分析:把sample2用式子列一下就能发现,每个点的权都要乘上好几条边的权,是哪几条边呢,就是这个点回到点1的路径上的那些边所以最后的树的花费可以写成 res = sum{ (点权) * (该点回到点1的路径的边权和) } ,这些点 阅读全文
posted @ 2013-05-06 19:35 Titanium 阅读(1250) 评论(0) 推荐(0)
摘要:继续复习Dij变形,可用DP题意:求点1到点n,最大的载重量。转化为 ,1到n有多条路径,每条路径都有一个最小的边,求这些最小的边中的最大值定义d[v] 表示到点v的最小边最大值 , 从u到v,边权为w,那么首先选出 temp = min( d[u] , w) , d[v] = max(d[v] , temp)这是显然的,由u到v,边权为w,要经过这条边,必须流量不能比w大,否则流不过溜过去之后,选最大的用优先队列+dij变形来做,改变的只是松弛的条件而这中问题,用dp来解也是显而易见的,不写了,以前写过#include <cstdio>#include <cstring&g 阅读全文
posted @ 2013-05-05 23:08 Titanium 阅读(263) 评论(0) 推荐(0)
摘要:最短路题意: 强调是有向图 , n个点(1到n标号)m条边,求出点1到所有点的最短路之和 + 所有点到点1的最短路之和什么?求一次最短路,然后 x 2 就是答案? 这样是错的,如果是无向图的话可以这样,因为可以逆回去走。但是有向图显然不是,点1到点a的最短路,和点a到点1的最短路是完全不同的,值不同走过的路径也不同.要求点1到所有点的最短路,直接运行一次最短路即可。但是要求所有点到点1的最短路,难道要对所有点运行一次最短路吗?一看点数就可以否定这个想法。可以这样想,如果点a到点1存在最短路,那么把这条路径的边全部取反,就是点1到点a的最短路了。所有在求了第1次最短路后,将 整个图的边取反,再求 阅读全文
posted @ 2013-05-04 22:38 Titanium 阅读(1131) 评论(0) 推荐(0)