图论
leohujx
这个作者很懒,什么都没留下…
展开
-
poj_1062
这道题目不难,只要建好图就行。我们在图中新建一个新的点0,从0出发的到其他点的值就是该物品的原价值,那么我们新建立一个二维数组price[i][j],表示i物品兑换j物品的价值,则price[0][i]就是i物品的原价值。然后我们遍历每一个物品,对于每一个物品,我们都假设它是当前等级最高的那个,然后我们把比它价值高或者和它价值差超过m的那些物品设置为不可访问,接着用最短路跑一遍。经过n次循环后,输出原创 2015-06-16 16:15:11 · 432 阅读 · 0 评论 -
poj 1330
LCA裸题。 这里我用tarjan(dfs+并查集)的方法进行离线处理。 这是第一个例子的图,题目中求的是16和7的LCA,那么这个过程是这样的。 我们从根节点,即8号开始搜索,每次计算完LCA(u)以后,那么我们就处理了以u为根节点的子树,比如我们计算了4,6,15,7那么这棵子树就为一个集合,然后它们的根节点为4,然后再从4往右边走,当我们走到16时,发现7已经被处理过了,说明此时它们原创 2015-09-17 20:38:12 · 257 阅读 · 0 评论 -
AOJ 2249
优先队列+Dijkstra 因为题目中所给的点的个数多达10000个,而且看得出来要求最短路,但是普通的Dijkstra的效率为O(n^2),这显然是不行的,那么我们可以用优先队列+DIjkstra。题目中说了,要求去掉一些边,使得总花费最少,但是去掉边后不能影响从源点到其他所有点的最短路。那么与普通的相比,就是当dis[v] == dis[u] + r [u] [v]时是cost[v]小还是co原创 2015-09-30 23:24:17 · 385 阅读 · 0 评论 -
scu 4444 travel
链接这道题目很新颖,但是不会做(:зゝ∠)。看了下叉姐的代码,简单易懂。 题目大意是给你n个点,我们知道最多存在n*(n-1)/2条边,其中m条边是题目给出的,经过它们需要花费的时间为a,另外剩下的花费时间为b(为了方便,我们就叫a边和b边)问你从起点到终点(1号点到n号点),需要花费的最短时间是多少。 思路是这样的,我们先用临界表将所有的边存储下来,然后在以起点为开头的邻接表中找是否有直接到终原创 2015-10-02 17:09:40 · 738 阅读 · 0 评论 -
hdu5348
题目大意就是有n个点,m条无向边,现让你将这m条无向边改为有向边,使得每个点的|入度-出度|v,0代表v-->u。逐点逐边搜索即可。如果对于某个点u,它的入度in[u]>=出度out[u],那么就正向搜索,我们找一个与u相连且不等于u的点v,假设点v的in[v]时间复杂度为O(n+m),要达到这个效率,我们用链式向前星来存储边,然后用head[u]=edge[i].next来删除已经访问过的边。但原创 2015-08-09 13:02:55 · 377 阅读 · 0 评论 -
poj_3259
这道题目是求最短路图中是否存在负权回路,我们用bellman_ford即可。做此题时用了下链式向前星,因为之前没怎么用过。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<tim原创 2015-06-13 23:41:21 · 325 阅读 · 0 评论 -
poj_1860
此题是求“最长路&&回路”,最长路的话我们只要把最短路的条件改一改就行,既然要求回路,那么我们就用bellman_ford来求,因为每求一个点后,都有可能使得最长路松弛,所以我们遍历n-1遍所有的边,如果之后还有可以松弛的边,那么说明这个图中存在着回路,也就是对于本题,货币可以无限的换,无限的增长。#include<stdio.h>#include<iostream>#include<strin原创 2015-06-13 22:40:37 · 349 阅读 · 0 评论 -
poj_2240
此题不难,套一下稍微改变的Floyd算法就行,因为没要求起点,所以我们计算下全局的最长路,看看最后回到自己本身以后路径长度是否大于初始的1.0即可。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>原创 2015-06-16 17:47:52 · 288 阅读 · 0 评论 -
poj_2253
最短路的变形。在一般最短路中,dis[i]的意思表示的是从源点到i点的最短路径,在此题中,我们把dis[i]的意思理解为从源点到i点的路径中使得最长路最短的长度。那么松弛条件也要相应的变化。 改为for(int j=0;j<n;j++) if(!vis[j]&&dis[j]>max(mmin,mp[flag][j])) dis[j] = max(mmin,mp[flag][j]);这样原创 2015-06-16 16:52:06 · 286 阅读 · 0 评论 -
poj_1789
题意就是让你求一个最小生成树,一共有n个点,每两个点之间的距离就是字符串相对应位置上不同的字母个数,由题可知,这是一个完全图。建好图后,我们任意选择一个起点(这里我们选择0点),跑一遍Prim就能够计算出最小生成树的长度。#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorith原创 2015-06-16 22:15:57 · 289 阅读 · 0 评论 -
poj3662
艾玛,这道题目一个星期前卡了我好久,所以后来都没信心做这个专题了,今天重拾打了一遍,过了,竟然就过了,太TM开心了。 题意就是给你n个点,它们之间有p条边,起点是1,终点是n,让你用电话线从1连接到n,其中的k条线已经提供给你了,无限长,剩下的得自己铺,代价就是铺的所有电话线中最长的拿一根,求最短的代价。 转换为二分,二分那个最短的距离,然后用优先队列+最短路来计算从起点到终点的最短路,我们要注原创 2015-10-22 12:11:03 · 468 阅读 · 0 评论