图论
ナナ色のブランク
这个作者很懒,什么都没留下…
展开
-
UVA 10269 Adventure of Super Mario(分层图最短路+Floyed预处理)
题目链接分析:分层图做多了读着读着题目就不由自主想到,这题也没啥需要注意的吧,每层图代表使用了几次加速,一共k+1层图,挨个建就行了。唯一一点就是城堡是不能跨过的,也就是可以作起点也可以作终点,但不能作为中转点,floyed预处理一下也ok了,最后跑最短路就行了。#include<bits/stdc++.h>#define MAIN main#define PII pair<int,int>#define x first#define y second#define l原创 2021-02-23 20:48:17 · 136 阅读 · 0 评论 -
UVA 10537 The Toll! Revisited(dijkstra+字典序路径输出+数学公式或二分答案)
题目链接题目大意:小写字母代表村庄,大写字母代表城镇,进入村庄需要缴纳一单位货物,进入城镇每二十个货物需要缴纳一个,问从起点到终点缴纳货物最少的路线是哪个,最小需要在起点准备多少货物,并输出这个路线,有多个路线时输出字典序最小的那个。分析:进入一个点需要的花费可以看作边权,要求起点货物最小,那么可以从终点开始逆推,按照最短路前进,同时在松弛操作的同时记录下字典序最小的那个,然后将该结点入队,看看是否能扩展出一条最短路来。进入城镇所需的花费需要计算一下,说繁琐也不繁琐,就是一个公式的推导,不想推也可以直原创 2021-02-18 10:43:28 · 166 阅读 · 0 评论 -
UVA 658 It‘s not a Bug, it‘s a Feature!(隐式图搜索+最短路)
题目链接题目大意:给定一个长度为n的字符串,每个位置代表一个bug,然后给定m个补丁,每个补丁有两个字符串,第一个是初始序列(‘0’表示bug是否存在都无所谓,‘+’表示必须存在,‘-’表示必须不存在),第二个是打上补丁后的序列(‘0’表示不变,‘-’表示不存在bug,‘+’表示存在bug)初始时你的序列是存在所有bug的序列,每个补丁都有一个花费时间,问通过打上补丁消除所有bug所需的最小时间。分析:通过手动模拟样例就能大概理解题意,我们可以把当前序列看成一种状态,用一个n为二进制数或长度为n的数组来原创 2021-02-16 17:14:22 · 1883 阅读 · 3 评论 -
UVa 1416 Warfare And Logistics(最短路树)
题目链接题目大意:给定n个点m条边的无向图,令c=∑i=1n∑j=1nd(i,j)\sum_{i=1}^{n}\sum_{j=1}^{n}d(i,j)∑i=1n∑j=1nd(i,j),任务是求出删掉一条边后最大的c值(其中d(i,j)表示i到j的最短距离)分析:求全源最短路可以Floyed也可以n次单源最短路,复杂度分别是O(n3)和O(nmlog(n))O(n^3)和O(nmlog(n))O(n3)和O(nmlog(n))如果暴力枚举删掉的边的话,复杂度都要再加一个m,这个题m最大可为1000,明原创 2021-02-12 18:41:59 · 1939 阅读 · 3 评论 -
HDU 4081 Qin Shi Huang‘s National Road System(枚举+倍增优化)
题目链接题目链接:给你n个点,每个点都有权值,可以免费连接两个点,然后再选择n-2条边构成一个生成树,使得免费连接的两个点的权值和/n-2条边的长度和比值最大。输出这个最大值。分析:很容易可以想到枚举哪两个点免费连接,然后用并查集维护,构建最小生成树,但这样做明显不现实,n=1000,时间复杂度不允许,所以否决这个方案。反过来思考,如果不是在枚举点后求最小生成树,而是枚举最小生成树上的两点,因为树上路径是唯一的,所以求出这两点间最大的一条边,用总权值减去这一条边的长度,最后维护一个最小值就行了。求路原创 2021-02-05 17:46:03 · 162 阅读 · 0 评论 -
hdu 2489 Minimal Ratio Tree(最小生成树+dfs枚举/状压)
题目链接题目大意:从n个点选m个点构成一颗生成树,要求这个生成树的比率最小。分析:看到数据范围就很明显了,n个点选m个点,dfs暴力枚举或者状压挨个枚举,然后更新答案就可以了。下面是状压#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#include<queue>#include<map&g原创 2021-02-05 15:01:44 · 190 阅读 · 1 评论 -
POJ 3621 Sightseeing Cows(最优比率环+spfa的dfs判环优化)
题目链接题目大意:给你一个有向图,每个点都有一个权值,每条边都有一个长度,需要找到一个各点权值和/各边长度和 最大的环出来,输出这个比值。分析:假设结点权值为wiw_iwi,边的长度为lil_ili设所求的比值r=∑i=1mwvi∗xi∑i=1mli∗xi(xi=0或1,1<i<m)r=\frac{\sum_{i=1}^{m}w_{vi}*x_i}{\sum_{i=1}^ml_i*x_i}(x_i=0或1,1<i<m)r=∑i=1mli∗xi∑i=1mwvi∗xi原创 2021-02-03 17:55:59 · 136 阅读 · 0 评论 -
NC50381 道路和航线 (spfa+slf优化)
题目链接题目大意:很简单,从源点s到其它所有点的最短距离,就是单源最短路的模板。分析:很板子,只不过需要加一下slf优化,不然超时,就是为了记录一下。#include<bits/stdc++.h>#define MAIN main#define PII pair<int,int>#define x first#define y secondusing namespace std;typedef long long ll;const double eps=1e-8;原创 2021-02-02 17:23:31 · 146 阅读 · 0 评论 -
HDU 1839 Delay Constrained Maximum Capacity Path(二分+最短路)
题目连接题目大意:给一张图,然后每条边有容量和花费,皆为无向边,一条路径可以运送的货物量最大是这条路径上容量最小的边的值,问从1到n最多能运送的货物量是多少,如果超过时间T的话则这条路径视为无效。分析:首先可以看到货物运送量是一条路径上的最小值,而我们要让运送量最大,所以就是要让最小值最大,很容易想到二分这个最小值,这个最小值就是路径上的最小值,然后把问题转换成了判定问题,当一条边的容量小于这个值时这条边不能被使用。然后当从1到n运送的时间大于T时也不行,所以我们每次走路都按最短路径去走一定是最优的。原创 2021-02-02 16:37:49 · 100 阅读 · 0 评论 -
洛谷P1027 [NOIP2001 提高组] Car 的旅行路线(计算几何+最短路)
题目链接题目大意:给你s个城市,每个城市有四个机场,每个城市内机场两两之间有直达路径,所有城市内两两之间的机场都有可直达路径,问从a到b城市最短的路径是多少,出发点和结束点机场任选。分析:思路大致就是对所有点建边,然后folyed或者四次单源最短路更新答案即可,关键点是建图。然后问题关键要解决的就是矩形的第四个点怎么求,我们可以利用勾股定理,求出给定三点见两两之间的距离,然后判断哪条边是直角边,最后直接计算坐标即可。(具体看代码)#include<bits/stdc++.h>#defi原创 2021-02-01 18:08:14 · 410 阅读 · 0 评论 -
HDU 3986 Harry Potter and the Final Battle(枚举+最短路+注意重边处理)
题目连接题目大意:给一个n个点m条边的图,求在删掉一条边的情况下从1到n最短路的最大值。分析:同hdu1595,但与它不同的是这个题是由重边的,所以要注意对重边的处理,这里用链式前向星存图,假设删掉的边为num,那么num^1就是其反向边,每次枚举这两条边不可使用就好了。#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<queue>原创 2021-01-29 19:09:15 · 124 阅读 · 1 评论 -
HDU 1595 find the longest of the shortest(枚举+最短路)
题目链接题目大意:给你一个图,然后求出从1到n在去除一条边的情况下最长的最短路。分析:去掉边我们很容易想到枚举去掉那些边,然后每枚举一条边去做一次最短路,然后取一次最大值。然后我们还可以注意到去掉的这条边一定是最短路上的边,因为她每次都按最短路径走,去掉的如果不是最短路上的边的话那么对最终结果是没有任何影响的。n最大只有1000所以复杂度随便一算是绝对不超时的。#include<iostream>#include<cstdio>#include<algorithm&原创 2021-01-29 17:18:07 · 122 阅读 · 0 评论 -
NC51266 Network(边双连通缩点+树链剖分)
题目链接题目大意:给你一个n个点m条边的图,一共有q次操作,每次给x和y两点间加一条边,问每次操作完后图中有几条割边。分析:很明显是要求割边的数量,但是不同的是这次是给q次操作,每次操作完用tarjan算法明显不现实,所以我们考虑有没有某种数据结构去优化这个过程。考虑缩点,割边即为缩点后树上的一条边,那么我们考虑给边赋值,每次询问就求缩点图上两点间权值之和,可以用树链剖分去实现这个过程。我们用ans表示整个图上割边数量,每次用ans-ask(x,y),输出即是答案。注意点:边双连通缩点注意平行边的处理原创 2021-01-27 17:19:53 · 101 阅读 · 0 评论 -
洛谷P2680 [NOIP2015 提高组] 运输计划(树上差分+二分)
题目链接题目大意:给你一颗树,再给定m条路径,你可以使树上一条边的权值变为0,要求这m条路径的最大值最小。很暴力的想法就是枚举n-1条边挨个删,这样是超时的。但是看到最大值最小,很容易想到二分答案,然后开始去思考这个最小值是否满足单调性。很明显,如果完成这m个任务需要a的时间,那么必然存在一个b使得b>a,并且可以用b时间去完成这m个任务。然后就可以直接去二分这个最小值了,考虑怎么判断答案的正确性。我们注意到,如果这m条路径中有k条的值是大于我们二分的这个mid的,那么我们归零的这条边必须原创 2021-01-21 20:05:44 · 166 阅读 · 0 评论 -
HDU 1827Summer Holiday(缩点+tarjan算法)
题目链接点这里!!思路:模板题。首先强连通分量内部的点都可以互通。那么就求出有几个强连通分量,把每个强连通分量看成一个点,考虑每个连通分量缩点的入度,入度为零则表示没有其它点能传给它,所以必须要花费钱给他传递。#include<iostream>#include<queue>#include<vector>#include<cstdio>#include<map>#include<string>#include<f原创 2020-08-06 17:21:51 · 132 阅读 · 0 评论 -
判断图连通性的三种方法(并查集/dfs/bfs)
首先要了解什么是连通图,这是百度百科百度百科——连通图1.并查集首先统计连通分量的个数,如果一个图中连通分量个数大于1则肯定不是连通图,等于1则是连通图。int n,m,f[N];int find(int x){ if(f[x]!=x) f[x]=find(f[x]); return f[x];}int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) f[i]=i; for(i原创 2020-08-04 22:30:15 · 4749 阅读 · 0 评论 -
HDU 4857逃生(拓扑排序+反向建边)
题目链接点这个!!!题目大意:给你几个约束条件,要求谁必须在谁的前面。同时要求编号越小的越要在前面,注意这里不是字典序,注意题目描述!!思路:首先这个毫无疑问,这种和优先级相关的基本拓扑排序没跑,但很明显这不是一种优先级了。两种优先级,一种是题目给出的顺序(即边),另一种就是编号顺序,从小到大。起初完全没思路,看了这篇非常nice的博客后懂了点这里!!!!我就不抄袭他的了,我就单纯说说自己的理解吧。首先我们都知道如果一个点的入度为0那么他肯定是优先级最高的,也就是起点,如果从入度这个方面思考这个题原创 2020-08-04 18:05:57 · 144 阅读 · 0 评论 -
hdu 2647 (拓扑排序,注意题目要求反向建边)
题目链接点这里!!!!题目大意:就是你给n个人发工资,他们有各自的要求,要求a的工资必须大于b之类的,每个人工资最少是888(吉利),要你求出最少的工资,若不能满足他们的要求,则输出-1。输入a b表示a的工资必须大于b。(没有重边)思路:只要看到这种要求什么什么必须在某件事之前的题大部分都和最后的拓扑序列有关。题目中要求a>b,那么就是说在给b发完工资后,在b的工资基础上加1然后发给a就行了(又是一个先后关系),所以求出最后的拓扑序列就ok了。但是有一个点可能不过脑的话会错,就是输入顺序是原创 2020-08-04 13:03:17 · 147 阅读 · 0 评论 -
POJ 1270 Following Orders(拓扑排序+dfs回溯)
题目链接题目大意:给你一些字符变量,然后给你偶数对约束条件,规定若a>b,则a一定要在b的前面。最后按字典序从小到大输出所以可能序列。思路:因为题目规定了在约束条件下某个字符一定要在另一个字符的前边,换句话说就是在做某件事之前一定要做这件事的前一件事,这很明显就是拓扑排序。所以我们构造一个DAG,然后我们注意到要输出所有可能序列,很明显就是所有拓扑排序。bfs首先不能用,因为没办法回溯构造另一个拓扑排序,所以我们要用dfs,整个过程很基础,类似全排列。在我看来难点不是算法,而是输入,用get原创 2020-08-04 11:44:42 · 251 阅读 · 0 评论 -
D Coloring Edges (拓扑排序/dfs 判环)
题目链接题目大意:对一个有向图的边进行染色,要求一个环内的边颜色不能相同。思路:如果这个图无环,那么全部输出1,如果存在环,那么就让大节点指向小节点的边染成2,否则染成1。最多只有两种染色情况,因为一个环和另一个环之间不会存在联系,所以只要保证每一个环是合法的就行了。那么现在就只剩下判环了,可以拓扑排序或dfs。dfs时的判环和无向图不同,这一点需要注意。DFS:#include<bits/stdc++.h>using namespace std;typedef long lo原创 2020-07-24 17:15:56 · 172 阅读 · 0 评论 -
Codeforces Round #656 (Div. 3) E. Directing Edges (拓扑排序)
题目链接题目大意:题目大意:给你一个n个顶点m条边的图,其中一些边没有反向,其余边有方向,让你对每一条边赋一个方向,要求最终图不能形成自环。(没有重边)思路:首先我以前不知道拓扑排序,也是通过这个题才知道的,一开始我的想法是并查集判环,但看到方向就不会了。看了别人题解才知道拓扑排序。这里附上百度百科中的拓扑排序这道题很明显如果本身有环肯定不行,这也是最容易想到的,那么就剩下给无向边定方向了。为了让新产生的有向边不形成环,要先进行一次拓扑排序,然后让拓扑序小的点指向拓扑序大的点,这样肯定不会形成环。.原创 2020-07-18 18:35:29 · 227 阅读 · 0 评论 -
洛谷P1629 邮递员送信(dijkstra算法+反向建图)
原题链接思路:答案包含两部分1.从1到其它所有点i的最短距离的和。2.从其它所有点i到1的最短距离的和。注意是单向边。第一反应是用floyed算法但是1e3的数据量明显超时,最后我试了一下只有四十分。看了别人的题解知道了还有建反向图这种操作,我在这详细说明一下。建反向图其实就是:比如d[i][j]代表从i到j的距离,反向的话就是把d[i][j]和d[j][i]互换过来。原理是这样的:从u到v距离是w,那么从v到u距离也是w,单纯把方向反过来。说的话感觉总是说不到那个点子上,实在不行就画个原创 2020-06-16 20:21:31 · 441 阅读 · 0 评论 -
最短路径算法模板
写写模板有助于记忆和理解算法。。。Dijkstra单源最短路算法非常重要的一个单源最短路算法,适用于边权为正的情况。可以使用堆优化到O(mlogn)O(mlogn)O(mlogn)的复杂度,用于处理稀疏图时快的飞起。但对于非常稠密的图时比O(n2)O(n^{2})O(n2)还要慢。普通写法void dijkstra(int s){ for(int i=1;i<=n;i++)...原创 2020-04-18 23:47:40 · 193 阅读 · 0 评论