图论
文章平均质量分 71
brainache
这个作者很懒,什么都没留下…
展开
-
hdu1863 (最小生成树)
实现了一个prim,然后胡乱套到题里面 对于不联通的情况,胡乱判断一下居然ac了 #include using namespace std; const int maxn=10000; int main() { int dist[maxn]; bool ontree[maxn]; vector >g[maxn]; //输入 int n,vt;原创 2017-12-09 10:52:50 · 192 阅读 · 0 评论 -
hdu 5695 Gym Class (优先队列+拓扑排序)
题意:一群人编号1~n,给他们拓扑排序,已知其中的邻接关系,要求得到的拓扑序中,每个元素包括自己以及他前面的编号的最小值最大,求所有人的这个值的和。 思路:把正常拓扑排序的队列换成优先队列即可 //做的时候手滑把用于记录的变量和循环的变量名写重了结果t了一个晚上 //发现用for初始化比用memset初始化速度快,而且更省内存 #include using namespace std;原创 2018-01-08 21:09:59 · 231 阅读 · 0 评论 -
hdu1811 Rank of Tetris (并查集+拓扑排序)
题意:有n个人,以0~n-1编号。现在给出m个形如a>b,a=b,ab,b>c,c>a或者a=b,a>c,c>b这样的情况,信息不完全指无法按照当前给定结果判断出唯一顺序(没有加等号的并不会按照编号大小决定顺序)比如有a,b,c三个人,但是给的顺序只有a>b,a>c,这样就无法确定b,c谁先谁后。对于同时出现矛盾和信息不完全,输出矛盾。 思路:这题的思路是并查集加拓扑排序,并查集起到一个预处理掉原创 2018-01-05 21:20:10 · 263 阅读 · 0 评论 -
图的存储方式
图是点和点之间的关系,存储图,主要问题就在怎么存边。 为了区别每个点,理论上要把每个点标号,但因为顺序无所谓,一般就直接按照读入的顺序,一个一个往后面排。 于是,对于需要存关于点的性质时,只需要开个数组,单独存进去就行了。单独存点这事就很方便。 并查集法 如果能确定这个图是个树,或者在需要判断这个图有没有树的性质(是否联通,是否有环),可以按根并查集差不多的方法来存点之间的关系原创 2017-12-25 14:41:08 · 2497 阅读 · 2 评论 -
二分图匹配与匈牙利算法
匹配,指一个边集,且其中所有边没有公共顶点。 匈牙利算法能求出二分图上的最大匹配。 之前看大部分讲解里面都说到了增广路,不过有一篇博客在没有说增广路的情况下讲清楚了匈牙利算法 大概是个这样的思路: 假设顶点集是a,b,每次从a上面选择一个元素ai,往b上面找匹配。如果直接找到了一个和ai有边且没匹配过的bj,那么ai,bj匹配,开始ai+1的操作 如果在找匹配的时候,手头上原创 2017-12-27 15:48:50 · 246 阅读 · 0 评论 -
dj的邻接矩阵实现
#include using namespace std; const int maxn=100,bignum=100001; int g[maxn][maxn],dis[maxn],t[maxn],siz; bool state[maxn]; void creat(int k) { memset(g,0,sizeof(g)); for(int i=0;i<=siz;i++)原创 2017-09-22 14:40:52 · 307 阅读 · 0 评论 -
floyd算法-求图中任意两点间最短路
floyd算法是一种可以在o(v^3)求出一个图中任意两点最短路的算法 输入:邻接矩阵d 输出:直接在d上面修改,每个元素d(i,j)代表点i到点j的最短路 这个算法的代码非常短,一眼看上去非常暴力 for(int k=1;k<=v;k++) for(int i=1;i<=v;i++) for(int j=1;j<=v;j++)原创 2017-12-19 10:35:18 · 2405 阅读 · 0 评论 -
网络流的基本概念
网络N: (V,X,Y,A,c),其中,V:点集,X:源点集,Y:汇点集(多源多汇的情况可以由虚拟源,汇点的方式转换成单源单汇,对于单源单汇,此处可写成x,y),A:弧集,c:容量函数,c(a)表示弧a的容量。 (可行)流f:,f(a)表示弧a的流量,f+(v)表示v的所有出弧的流量和,f-(v)表示v的所有入弧的流量和,f满足容量约束:f(a)流量守恒 :对不为x,y的点,f-(v)=f+(原创 2018-01-02 09:50:27 · 493 阅读 · 0 评论 -
图论学习记录
最小生成树 -prim o(|e|+|v|^2) 上树法,开始时随便选一个点,每次往已有树上面加离树最近的点以及这条边。 -kruskal o(|e|log|e|) 加边法,每次选择不会产生圈的最短的边。 单源最短路 最短路问题的统一手段是松弛,每种方法的区别主要在松弛顺序 -Be原创 2017-12-26 19:05:23 · 266 阅读 · 0 评论 -
dinic算法
dinic算法是一种求最大流的算法。 这个算法用到了“层次网络”的概念 定义“顶点的层次”lev(v):,表示原点到这个点的最少边数有多少(也可以相反的定义为他到汇点的最少边数有多少,在这里没有本质区别,实现的时候改下判定条件就行) 层次网络就是把所有顶点都标上层次的网络了 那么这个玩意有什么用呢,他可以使搜索的效率提高 dinic的思路仍然是 找路->增广 的想法,少找些路原创 2017-12-26 09:16:24 · 978 阅读 · 0 评论 -
单源最短路与bellmanford
单源最短路问题,就是对一个边带权图G和其上一点s,求G上每一点到s的权最小路 性质: 1.最短路上不会有环 2.将达不到或者暂时达不到的点的距离习惯记做无穷 3.该问题满足最优子结构,即最短路的子图也为最短路 如何记录:对每个节点v,维护一个值v.pi,表示这个点的前驱节点。求解完成之后使用他构造最短路径树即可、 基原创 2017-12-16 12:05:35 · 212 阅读 · 0 评论 -
kruskal算法求最小生成树
kruskal算法是一种使用贪心思路求解无向图的最小生成树的算法。 其大体思路为:将边按权重排序,然后每次选出权最小且不使图产生环的边,作为树的边挂上树。 具体来讲就是这么两个步骤: 1.把边按权重排序。 2.依照1的顺序遍历边: 使用一个并查集来判断加进这条边后图中是否有环。原创 2017-12-15 20:55:10 · 1305 阅读 · 0 评论 -
edmonds-karp算法求最大流
ek算法能在o(v*e^2)时间里求出最大流 思路:每一步对残量网络进行一次s到t的bfs,以这次bfs的结果作为增广路,更新残量网络。用bfs找增广路可以避免回头的情况。原创 2017-12-20 21:11:30 · 1250 阅读 · 0 评论 -
hdu3790最短路径问题
题意:求一个无向图的单源最短路,其中每个边有两个权重,第一个权重值相等时路径的大小由第二个权重决定 直接套spfa板子 #include using namespace std; int v,e,s,t; const int maxv=1005; struct w { int d,p; bool operator <(const w b) const {原创 2017-12-22 11:02:18 · 285 阅读 · 0 评论 -
spfa
spfa是一个求解最短路的算法 思路:按类似bfs的顺序进行松弛 定义一个队列q,以及一个数组vis[]记录每个节点是否在q中 每次有点出入队时修改vis[],确保能判断每个点是否在q中 先将起点s入队 然后开始循环操作,队空为停止条件 q出队一个点,记做v,将v的所有邻点松弛,对于可以松弛的点,若它不在q中就将其入队。 判断负权回路:原创 2017-12-18 11:24:47 · 764 阅读 · 0 评论 -
塔杨板子
#include <bits/stdc++.h> using namespace std; const int maxn=10010; vector<int>gra[maxn]; int dfn[maxn],low[maxn],ind,v,e; bool instack[maxn]; stack<int>s; void init()//点从1开始 { ...原创 2018-05-09 21:22:46 · 307 阅读 · 1 评论