ACM的第七乐章--Tarjan lca

tarjan 求解lca主要利用并差集的想法:首先遍历树,从叶子节点开始向上合并成一棵棵的子树,然后子树并子树,就成了一棵树了。

查找是在合并的时候进行的,expus,tlca,先从u节点进入s,把s并到u下面,然后发现t没有被访问,退到u,再进入t,同样把t并到u下面,发现s被访问过了,那么slca也就是s,tlca了,也就是并差集里的f[s]。当然,f[s]会变的:假设当前f[s] = u; f[u] = u; u并到v的时候,也就是f[u]=v; 相应的f[s] = v。这也就是tarjan求解lca的关键方法。

poj 1330 tarjan lca

http://poj.org/problem?id=1330

这个题裸lca,模板直接上。

poj 1470 Closest Common Ancestors

http://poj.org/problem?id=1470

裸LCA:读入数据很诡异。

hdu 2586 How far away ?

http://acm.hdu.edu.cn/showproblem.php?pid=2586

也是一道很裸的LCA,只不过卡了一下栈,要自己开大点栈才能过(c++)。

思路:选1为根节点,先得到从根节点出发到每个点的距离,这样任意两个点的距离为:dis(u)+dis(v)-2*dis(lca(u,v)).

hdu 2874 Connections between cities

http://acm.hdu.edu.cn/showproblem.php?pid=2874

裸LCA,处理森林的无向图。

思路:给每棵树一个唯一的编号,查LCA的时候,判断一下是不是在同一棵树下就行了。

hdu 3594 Cactus

http://acm.hdu.edu.cn/showproblem.php?pid=3594

这是一个很好的题目,很巧的利用的low[u]和dfn[u]。如果low[u]!=dfn[u],则说明已经存在环,如果我们访问u点时发现low[u]!=dfn[u],则说明有一条边在两个环上了。

hdu 1827 Summer Holiday

http://acm.hdu.edu.cn/showproblem.php?pid=1827

题目意思:在一棵有向图中,每个点都有一个权值,求有多少个连通分量;在某个连通分量中,求出可以遍历这个连通分量的点,使得这个点的权值最小。

思路:如果没有环,则起点就是所要求的点。如果有环且环上的点都能遍历这个边通分量,则选择环上权值最小的点。

定义:每次选择的初始点为根。

选择没有遍历过的点作为根,进行tarjan遍历,如果一开始就进入了环,则要把整个环都标记到根上,取环上的最小值作为根的权值。如果发现可以到达其它根,则把该根去掉。

hdu 3072 Intelligence System

http://acm.hdu.edu.cn/showproblem.php?pid=3072

题意:在一个有向图中,有多个连通分量,每个连通 分量都会有一个根节点,求当满足每个根节点都可以到其它根节点时的最小权值。环中的间的权值都为0.

思路:因为有环,而已环中的权值为0,所以要进行缩点,缩点后重建图,所得到的图将没有环。然后枚举每个根节点,进行记忆化搜索就好了。

hdu 4005

http://acm.hdu.edu.cn/showproblem.php?pid=4005

思路:缩点之后形成一棵树,连任意两个点都能之后形成一个环,那么破坏这个环上的任意一个边都不会破坏图的连通性,我们只有破坏不在环上的边才能使图不连通。由于边是任意加的,我们当然要使最小的边尽量都在环里面。好了,这样的话我们可以先找一条最小边,因为如果最小边不在环里的话,那么破坏一个最小边就可以了。找到最小边了之后,以最小边的两个端点分别向两侧遍历一条路径,使得路径上的边的值都尽量小,也就是说使不在路径上的边的值的最小值尽量大,怎么做到呢?稍微想一下,在遍历的时候,对于每个点,他与各个儿子边的次小值(儿子边实际包含儿子子树上最小的边)的最小值就是答案,这样的话遍历两遍就好了。

ps:发现tarjan的写法有点不一样,如果按常规写,就wa。求解中~~~

poj 2762

http://poj.org/problem?id=2762

题意:给一个无向图,问对任意的两个点x,y,是否都存在一条路径从一个点出发到达另一个点。

思路:先用tarjan对无向图进行缩边和求弱连通分量,如果弱连通分量不为1,则No;然后重建无向图,判断是否是线树,是则Yes,否则No。

 注意:缩边后的图不一定是棵标准的树。

 

poj 1236 Network of Schools

http://poj.org/problem?id=1236

题意:1.要求出至少发分配多少站点,使所有点都能收到,即求入度为0的分量。

        2.求要添加多少点,使任意一个点发送物品,其他点都能收到物品,即求Max(入度为0的分量个数,出度为0的分量个数)。

注意单点的情况.

 

poj 2186 Popular Cows

http://poj.org/problem?id=2186

题意:若A认为B好,且B又认为C好,则可以推出A认为C好,现给一个这样的无向关系图,求出有多少个点,所有人都认为它好。

思路:先对图进行tarjan去环缩边成点,并统计环中点的个数,然后查看一下出度为0的点是否为1,如果是则这个点代表的环里的点的数目,否则puts("0");

 

poj 3114 Countries in War

http://poj.org/problem?id=3114

题目大意:战争期间的通信问题,同一个国家的城市间可以互相通信,距离可视为零,不同国家的城市间根据所给路径,求解最短路.

思路:对于有向图中的环,先进行缩点重建图,然后对每个点直接spfa。

 

poj 3180 The Cow Prom

http://poj.org/problem?id=3180

题意:给一个无向图,求出节点数据大于1的边通分量有多少个。

思路:直接tarjan缩点统计。

 

hdu 3639 Hawk-and-Chicken

http://acm.hdu.edu.cn/showproblem.php?pid=3639 

题意:给一个无向图,求出拥有最多祖父的节点。

思路:先tarjan缩点,可以知道只能出现在叶子节点,所以反向建图,对每个入度为0的节点进行遍历统计。

 

hdu 3394 Railway

http://acm.hdu.edu.cn/showproblem.php?pid=3394

题意:给定一个有N个点,M条边的无向图,求有多少条边没有在环内,有多少条边在至少2个环内。

思路:画一下图,很容易就想到在一个双连通图里,如果边数>点数,则此双连通图里的边都是在2个环内的。其实是错的,下面数据就是这样的特例:
6 6

1 2

1 3

2 3

3 4

3 5

4 5

其中3为割点。主要就是处理这种数据,在tarjan中,u是v的父亲,从v回溯到u,如果low[v]>dfn[u],则说明v到u没有环,如果low[v]==dfn[u],则说明u到v有环;这两种情况都要处理。

 

poj 1523 SPF

http://poj.org/problem?id=1523

题目大意:给定一个图,求这个图的割点,以及把该割点去掉以后的图有多少过连通分量。

思路:先求出所有的割点,然后暴力枚举这些割点求连通分量(1000个点)。

 

poj 2553 The Bottom of a Graph

http://poj.org/problem?id=2553

题意:给一个无向图,如果一个点v能够到达w并且w也能到v则w和v都称为一个sink,题目要求从大到小输出图中所有的sink点。注意叶子结点都是sink点。

思路:正如上面说的叶子结点都是sink,而且只有叶子结点才能形成sink点。因而先进行缩点,然后再求叶子结点。

poj 2375 Cow Ski Area

http://poj.org/problem?id=2375

题目大意:FR为自己的牛建立了一个H*W的矩形溜冰场,每一个小方格都有一个高度L,牛只能向相邻的小方格滑动(即上下左右),而且相邻的小方格的高度不能比当前高度高。为了使牛能够从任意一点到达任意其他的点。FR打算买一些ski lifts。它能够连接两个小方格,使得这两个小方格能够相互到达(与高度无关)。问至少需要多少ski lifts。使得牛能够从任意一点到达任意其他的点。

解题思路:将此矩阵看成一个图。如果一个小方格能过到达相邻的一个小方格。那么它们之间就相当于有一条边。然后对此图求强连通分量。ans = Max(入度为0的连通分量数目,出度为0的连通分量数目)。还需要注意的就是如果此图本身就是一个强连通分量,那么答案就是0了,而不是1.(不然会WA)。

ps:如果用g++交的话,tarjan要写成非递归的,不然RE。

poj 3160 Father Christmas flymouse

http://poj.org/problem?id=3160

题意:给出一个有向图,每个点有一个点权,点权可能是正也可能为负,一个人从某点出发,沿着一些路,访问结点,或者仅仅是路过这个结点,而不去访问,最后求他能访问到的最大的点权和。

思路:在有向图里,经过一个点,可以访问,也可以不访问,所以可以把环上的值都取完,其它的能达到就取。因此先进行缩点聚值,然后dfs+记忆化求最大值。

 

poj 3177 Redundant Paths

http://poj.org/problem?id=3177

题意:给一个无向图,问至少增加多少边,使得图中的每两个点都有两条不同的路径(两条路径不能有相同的边)。

思路:很明显,在环中的点都是满足条件的。所以首先是要进行缩点,记这时的叶子数为N,然后不断的加边成环缩点就会发现最后的结果就是(N+1)/ 2.

注意处理重边和N=1的情况。

poj 3352 Road Construction

http://poj.org/problem?id=3352

题意:给一个无向图,加上最少的边,使得改造后的图中去掉任意一条边后图依然连通。

思路:容易想到有环,则环上的点之间不会有问题,所以先首进行缩点,然后形成一棵树,记叶子数为N。再不断进行加边成环缩点可知最终结果为(N+1)/2。N=1时要特判。

poj 2942 Knights of the Round Table

http://poj.org/problem?id=2942

题目大意:N个骑士中某些骑士之间会有仇恨。骑士们开会时围坐在一个圆桌旁。一次会议能够举行,当且仅当没有相邻的两个骑士相互仇恨,且开会人数为大于2的奇数。若某个骑士任何会议都不能参加,那么就必须将它踢出。给出骑士之间的仇恨关系,问需要踢出多少个骑士。

思路:题目给出的是一对对相互仇恨的骑士,要使得骑士间环成一环,相邻没有仇恨,就要建图的时候就不能出现相邻有仇恨的。然后问题转化成求一个图里面的奇环,而在一个双连通图里,如果存在一个奇环,则这个双连通图中的每一个点,都能在一个奇环里(很蛋疼的想法)。所以最后就是在一个双连通图里找奇环,利用正负标记可以很容易求出。

hdu 2460 & poj 3694 Network

http://poj.org/problem?id=3694

http://acm.hdu.edu.cn/showproblem.php?pid=2460

题意:给一个无向图,每加入一条新边后,统计桥的数目。

思路:看完解题报告后,觉得自己傻了,几乎是暴力的方法。

用tarjan先统计图中的每个桥,并标记(以桥的出点作标记,即:uv是桥,标记v),并全部归结到以1为根的树中。

查询的时候用类似并差集的方法,不断向根走,同时检查经过的点是不是桥,当u=v的时候就可以退出了。

PS:如果原图是一线树,每次查询都选择两端点。可以知道时间复杂度为10^8,真不知道这样也可以过,只能说数据水了,或者说每加入一条边,保证可以去掉至少一个桥,但题目没有说。

(杭电上要用非递归写tarjan)

http://acm.hdu.edu.cn/showproblem.php?pid=4183
题意:在二维平面上给N个圆,每个圆的都有一种颜色光,每种颜色光的频率是不一样的。但保证一定有两种颜色:一种频率为400(最小),一种频率为789(最大)。
现在频率为400的为起点,频率为789的为终点。起点和终点是否能构成一个回路,且起点到终点的路径中光频率要单调递增,终点回到起点的路径中列频率单调递减。
思路:可以将圆看成一个点,圆之间相交看成点与点之间的边。这样就可以转化成在一个无向图里求给定点的环问题,因此可以直接套用tarjan求环。但要注意处理
无向图中的割点问题。至于路径的单调性,可以这样做,从起点出发,在没有走到终点时,保持路径都是按单调递增的走,当走过终点后,再找一条单调递减的路径回
到起点。

hdu 3861 The King’s Problem

http://acm.hdu.edu.cn/showproblem.php?pid=3861

题意:给出一个有向图,问最少能够分成多少个区域,使得每个区域内的任意一对顶点X、Y间,要么X能达到Y,要么Y能到达X。

思路:如果图有环,那么环内的点都是满足的,所以先缩点。然后就是有向图的最小路径覆盖,这就是祼二分图解决。

PS:最小路径覆盖 = 点数-最大匹配。 缩点后点数不是原来的N。

poj 1227 RoboContest

http://poj.org/problem?id=1227

题意:给一个无向图,然后在图中的一些点放置一些机器人,机器人在每一秒中都要向相邻的方向走去。问是否存在在某个时刻,每个机器人都在一个点上。

思路:利用奇偶性解决,如果图中存在一下奇数环,则一定满足;不然看某个到到达所以机器人的步数的奇偶性是否一样就可以了。

 

posted on 2012-06-21 09:49  aigoruan  阅读(611)  评论(0)    收藏  举报

导航