图论
图论
mfy的1号小迷弟
一个没有对象的野指针qaq
展开
-
洛谷P1073 [NOIP2009 提高组] 最优贸易(分层图+最短路)
洛谷P1073 [NOIP2009 提高组] 最优贸易(分层图+最短路)题意:带点权的有向图,每个点的点权表示,在该点购买或者卖出水晶球的价格。求从1到n,选择在一点购买水晶球,再选择在一点卖出水晶球后的最大收益。一个点可以多次经过。思路:方法一:缩点+dp(拓扑排序)方法二:分层图+最短路:图片来源每层边权为0,连接第一层的点到第二层的点的权值为点权的负数,表示在该点购买,连接第二层的点到第三层的点的权值为点权的正数,表示在该点卖出因为有负权,只能跑spfa...原创 2021-07-16 10:42:26 · 154 阅读 · 0 评论 -
牛客:飞行路线(分层图+最短路)
牛客:飞行路线(分层图+最短路)题意:一个带边权的图,求从s到t的最短距离,可以忽略k条边的权值。2<=n<=10000,1<=m<=50000,0<=k<=102<=n<=10000,1<=m<=50000,0<=k<=102<=n<=10000,1<=m<=50000,0<=k<=10思路:因为k很小,可以想不 到分层图,把原图看成k层,每层完全一样,再建新边把每层连起来,对于第一层的从原创 2021-07-16 10:30:16 · 252 阅读 · 0 评论 -
黑点==白点(MST)
黑点==白点(MST)题意:给一张无相连通图,每条边可能是黑边或白边,问是否存在一种生成树构成使得树上黑边数量==白边数量2≤n≤1e5,1≤m≤1e52\leq n\leq1e5,1\leq m\leq 1e52≤n≤1e5,1≤m≤1e5思路:1.把黑边权值看成1,白边权值看成0,对任意处于最小生成树和最大生成树边权和之间的值,都存在对应的生成树2.显而易见:将最小生成树其中的一条0边删去,那么最小生成树权值至多+1...原创 2021-07-15 19:43:05 · 110 阅读 · 0 评论 -
Dijkstra(最短路输出路径)
//时间复杂度O(n^2) #include<iostream>#include<cstring>using namespace std;const int INF=0x3f3f3f3f;const int maxn=1e3+5;int n,m,mp[maxn][maxn],dis[maxn],pre[maxn];//pre存前驱节点,用来输出路径bool vis[maxn];char s,t;void Dijkstra(int st){ memset(vis,0原创 2021-06-28 21:29:17 · 775 阅读 · 0 评论 -
Less complaints and more effort
#include<bits/stdc++.h>using namespace std;const int inf=0x3f3f3f3f;const int maxn=2e5+5;int n,m,q,dis[maxn][105];vector<int>mp[maxn],tmp[maxn];queue<int>p;void bfs(int now){ while(!p.empty()){ int x=p.front(); p.pop(); for(原创 2021-06-02 22:31:55 · 102 阅读 · 0 评论 -
Codeforces Round #675 (Div. 2)D. Returning Home
Codeforces Round #675 (Div. 2)D. Returning Home题意:题意为在一个二维平面上给定起点和终点的坐标,每次移动你只能朝着上下左右移动1的距离。但是这个平面上有m个特殊节点,当你的位置与这个节点的横坐标或者纵坐标相同时,你可以不花费任何时间直接到达这个节点的位置。询问从起点到终点最少要移动多少次(不包括瞬移到特殊节点的移动)。思路:考虑点与点之间的转移,一个点到很远的点,可以通过到x,y轴距离最相近的四个点,连边,建边跑dij#include<bit原创 2021-05-10 20:00:06 · 70 阅读 · 0 评论 -
2019 徐州 M. Kill the tree(树的重心的性质,子树合并)
2019 徐州 M. Kill the tree(树的重心的性质,子树合并)这题写得好爽题意求一棵有根树中,以每个节点为根的子树的所有重心思路前置芝士树的重心性质:1. 最大的子树最小2. 找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡3. 树中所有点到某个点的距离和中,到重心的距离和是最小的,如果有两个距离和,他们的距离和一样,则这两个点都是重心(即重心可以有两个)4. 把两棵树通过一条边相连,新的树的重心在原来两棵树重原创 2021-04-22 22:00:18 · 123 阅读 · 0 评论 -
UVA1613 K度图的着色 K-Graph Oddity(图的着色)
UVA1613 K度图的着色 K-Graph Oddity(图的着色)题意:给出一个结点数为奇数的无向图. 根据定义, 一个结点的度数即为它连接边的条数. 在给出的图中每一个结点的度数都不超过一个最小奇数 k. 你需要使用最多 k 种不同的颜色为图着色, 使得每个相邻结点的颜色都不同思路:dfs:先染当前节点再染其子节点,自底向下#include<bits/stdc++.h>using namespace std;const int maxn=2e5+5;int t,n,m,he原创 2021-04-11 12:28:32 · 268 阅读 · 0 评论 -
欧拉回路+并查集判断连通
洛谷UVA10054 The Necklace大玄学事件欧拉回路:并查集判断是否连通(也可以dfs)输出边要在dfs后面一排(why,玄学)#include <bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=1e4+5;int head[maxn],nex[maxn],to[maxn],tot = 1,vis[maxn],num[maxn],father[maxn];int d, f,a.原创 2020-11-23 13:01:46 · 99 阅读 · 0 评论 -
欧拉回路
洛谷Watchcow S题意从 111 号农场开始巡逻,每条路必须从两个方向各走恰好一遍,最后回到 111 号农场。**知识点**欧拉回路就是给一个图,存在一条回路把所边经过且每条边只经过一次。对于无向图:存在欧拉回路的条件:每个点的度都为偶数; 存在欧拉路的条件:有且只有两个点的度为一,且这两个点分别为起点和终点;对于有向图:存在欧拉回路的条件:每个点出度等于入度;存在欧拉路的条件:存在一个点出度比入度多一作为起点,存在一点入度比出度多一作为终点,其余点出度等于入度;求欧拉回原创 2020-11-21 21:43:22 · 101 阅读 · 0 评论 -
拓扑排序+bitset
AcWing 164. 可达性统计题目给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量。拓扑排序+bitset f[N]#include<bits/stdc++.h>using namespace std;const int maxn=50007;int n,m,head[maxn],to[maxn],net[maxn],top[maxn],d,k,in[maxn];void add(int a,int b){ to[++k]=b; net[k]=he原创 2020-11-12 22:16:13 · 88 阅读 · 0 评论 -
19银川:道路与航线(连通块+dij+拓扑排序)(SLF优化的SPFA模板)
农夫约翰正在一个新的销售区域对他的牛奶销售方案进行调查。他想把牛奶送到 T 个城镇,编号为 1∼T。这些城镇之间通过 R 条道路 (编号为 1 到 R) 和 P 条航线 (编号为 1 到 P) 连接。每条道路 i 或者航线 i 连接城镇 Ai 到 Bi,花费为 Ci。对于道路,0≤Ci≤10,000;然而航线的花费很神奇,花费 Ci 可能是负数(−10,000≤Ci≤10,000)。道路是双向的,可以从 Ai 到 Bi,也可以从 Bi 到 Ai,花费都是 Ci。然而航线与之不同,只可以从 Ai原创 2021-04-05 16:44:22 · 93 阅读 · 0 评论 -
洛谷P3201 [HNOI2009] 梦幻布丁(启发式合并)
#include<bits/stdc++.h>using namespace std;const int maxn=1e6+5;int n,m,k,col[maxn],head[maxn],nex[maxn],to[maxn],ans,sz[maxn];void add(int x,int y){ to[++k]=y; nex[k]=head[x]; head[x]=k; sz[x]++;}void merge(int s,int t){ if(s==t)return;/原创 2021-03-31 13:24:42 · 96 阅读 · 0 评论 -
棋盘覆盖(二分图匹配 + 奇偶图)
棋盘覆盖题意:#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<int,int>PII;const int maxn=1e2+5;int fx[4]={0,0,1,-1},fy[4]={1,-1,0,0};int n,t,ans;PII marry[maxn][maxn];bool vis[maxn][maxn],mp[maxn][maxn];bool dfs原创 2021-03-30 20:19:44 · 128 阅读 · 0 评论 -
牛客:Game Map(图论 + 思维)
Game Map题意:找最长的度数严格递增的路径长度思路:从度数从小到大,直接一次枚举。#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<int,int>pii;const ll maxn=2e6;int n,m,vis[maxn],to[maxn],nex[maxn],head[maxn],dp[maxn],ans,k,du[maxn];vector<原创 2021-03-28 20:23:25 · 183 阅读 · 0 评论 -
Codeforces Beta Round #28 B.pSort(思维 + 并查集)
Codeforces Beta Round #28 B.pSort(思维 + 并查集)题意:给定一个含有n个元素的数列,第i号元素开始时数值为i,元素i可以与距离为d[i]的元素进行交换。再给定一个1-n的全排列,问初始的数列可否交换成给定的样式思路:考虑到,如果 i 与di是在同一个连通块里,则一定可以通过交换得到目标序列#include <bits/stdc++.h>using namespace std;typedef long long ll;const long lon原创 2021-03-24 19:40:05 · 335 阅读 · 0 评论 -
Codeforces Round #485 (Div. 1) A. Fair(多源点BFS + 转换思维)
Codeforces Round #485 (Div. 1) A. Fair(多源点BFS + 转换思维)题意:nnn个点每个点都有一种商品,共有kkk种商品(从1到kkk编号),mmm条边(保证连通),求每个点为起点买到sss种商品的最小距离思路:如果以每个点为起点进行nnn次bfsbfsbfs肯定超时,想到以每种商品进行bfsbfsbfs,求出每种商品到第iii个点的最小距离。因为只有kkk种商品,只需要进行kkk次bfsbfsbfs。最后对每个点到kkk种商品的距离排序,取前sss个即可#i原创 2021-03-22 19:59:26 · 83 阅读 · 0 评论 -
CF574B Bear and Three Musketeers (思维 + 暴力)
题意:要从一群人中选择三个,给出一系列数对(i,j)表示第i个人和第j个人认识。现在给出要求,要选3个人,首先他们三个需要互相认识,其次,他们每个人除去另两个之外还认识的人的数目作为他们自己的recognition值,要求三人的recognition值之和尽量小,求这个最小值思路:规模在4000人,纯暴搜当然不可以。对于每对关系,建一个图,用数组G表示,两人i,j有朋友关系则G[i][j]=G[j][i]=1 没关系的值取0。然后可以暴搜了,筛掉三个人没有构成互相认识关系的取法,对每种符合要求的取原创 2021-03-17 19:37:00 · 69 阅读 · 0 评论 -
CF. Cut ‘em all!(思维 + 贪心)
Codeforces Round #484 (Div. 2). Cut 'em all!题意:一棵树,问删去最多的边后,使得剩下的每个连通块的点数为偶数思路:从子节点往父节点想,考虑前后dfs的数值变化,以及,把赋值判断当前节点和其所有子节点的点数和,若和为偶,则可以切去,并把当前节点权值和置为0;若为奇数则无解#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=1e5+5原创 2021-03-16 18:45:17 · 126 阅读 · 0 评论 -
差分约束
#include <iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;typedef long long ll;const long long mod=1e9; const int maxn=4e5+5;const int inf=1e9;int n,m,dis[maxn],head[maxn],nex[maxn],k,num,to[max原创 2021-03-14 15:38:28 · 84 阅读 · 0 评论 -
二分匹配~
1.求最大匹配A.匈牙利算法二分图里面,最大独立集(所有的点都没有关系,都是独立的)=顶点数-最大匹配bool dfs(int x){ for(int i=head[x];i;i=nex[i]){ int y=to[i]; if(vis[y])continue; vis[y]=1; if(!marry[y]||dfs(marry[y])){ marry[y]=x; return true; } } return false; } int main(){原创 2021-03-11 22:17:20 · 99 阅读 · 0 评论 -
SPFA双端队列优化
#include <iostream>#include <cstdio>#include <cstring>#include <deque>#include <algorithm> const int maxnode = 1e4+3;const int maxedge = 5e5+3;#define INF 2147483647 using namespace std;deque<int> Q;int first原创 2021-03-09 22:26:15 · 166 阅读 · 0 评论 -
最短路 + 二分
POJ3662Telephone Lines题意:从1到n,使第k+1大的路径尽可能小思路:二分找第k+1条电话线的长度d,用该长度d跑最短路算法,若最短路上的线路长度>=d的总数大于k+1,则该长度过短,反之过长,若最后无法找到则为-1,长度都可行则为0#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<cstring>us原创 2021-03-09 18:21:02 · 126 阅读 · 0 评论 -
传递闭包floyed
POJ3660 Cow Contest题意:N个选手,如果A比B强,B比C强,则A必比C强。告知若干个强弱关系,问有多少人的排名可以确定思路:设x个人比你强,y个人比你若,则当x+y==n-1时,才可以确定你的排名#include<iostream>#include<cstdio> using namespace std;const int inf=1e9;const int maxn=1e3+5;int mp[maxn][maxn],ans,n,m,x,y;int原创 2021-03-09 14:33:53 · 103 阅读 · 0 评论 -
最优比率环
题目:POJ 3621秒懂#include<iostream>#include<queue>#include<cstdio>using namespace std;typedef long long ll;const ll inf=1e9;const int maxn=4e6;const int N=2e6+5;int head[maxn],to[maxn],nex[maxn],vis[N],x,y,t,n,m,k,cnt[maxn];double原创 2021-03-08 20:06:07 · 84 阅读 · 0 评论 -
【模板】第K短路
#include<iostream>#include<cstring>#include<cstdio>#include<queue>using namespace std;struct edge { int v, w, next;} e1[100010], e2[100010];int head1[1010], head2[1010], tot; int n, m, k;int dis[1010];bool vis[1010];原创 2021-03-07 22:08:56 · 68 阅读 · 0 评论 -
平面图最小割 + 最短路做法
最小割:首先最小割在本题时可以这样感性理解:上图是一个你同学在钢铁厂打出来的一个铁架子。你把start处用手捏起来,end处自然垂下。用一个剪刀钳把这个铁架子拦腰剪成两半。如果剪成好几瓣(掉下来有好几个联通块的),那么显而易见,不如剪成两半(把刚才几个剪断的地方原样拼起来变成两个联通块)。我们把三角形看成是点,黑色的边看成是连接三角形的边,那么剪成两半的意思是……在三角形点的图上找一条从左下到右上的最短路径!沿着这条路径剪开就行了。具体思路技巧:把点与点连边转化为,面与面的连边。及把平面图转化为对偶原创 2021-03-07 21:14:09 · 338 阅读 · 0 评论 -
最短路+必须经过n个点+暴力排列组合
HDU3768最短路+状压DPn<=10,考虑next_permutation()枚举所有情况#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll inf=1e9;const ll mod=1e9+7;const int maxn=1e6;const int N=1e5+5;int head[maxn],to[maxn],nex[maxn],vis[N],x,y,t,n,m,k,n原创 2021-03-07 14:42:41 · 434 阅读 · 0 评论 -
次短路 + 统计路径数
HDU1688题目:统计最短路,及次短路的路径数对于每次更新:1.新路径比最短路径长度要小,那么最短路和次短路的长度和次数都要更新。2.新路径等于最短路的长度,那么只需要更新最短路的条数。3.新路径比最短路要长但是比次短路要短,那么需要更新次短路的长度和条数。4.新路径等于次短路径的长度,那么只需要更新次短路径的条数。#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll inf=1e9原创 2021-03-07 13:16:00 · 118 阅读 · 0 评论 -
floyed+dp
题目 hdu2833#include <bits/stdc++.h>using namespace std;const int maxn=5e5+5;typedef long long ll;const ll inf=1e9;const int N=305;int mp[N][N],dp[N][N],n,m;//DP[][]表示从i到j的经过点数 int main(){ while(~scanf("%d%d",&n,&m)){ if(n==0&&am原创 2021-03-06 22:40:32 · 55 阅读 · 0 评论 -
最短路:到一个点需要遍历其前序点
题目hdu3873 Invade the Mars#include <bits/stdc++.h>using namespace std;const int maxn=5e5+5;typedef long long ll;const ll inf=1e9;const ll mod=1e9+7;const int N=3005;int head[maxn],to[maxn],nex[maxn],kp[N],vis[N],in[N];ll dis[N],w[maxn],ndis原创 2021-03-06 20:29:09 · 60 阅读 · 0 评论 -
并查集缩点 + 拓扑排序
好题啊:题目hdu1811:题意:有n个人m个关系,例如1<2,1>2,1=2。问能否完全确定从第1到第n个人的大小关系。思路:若没有‘=’,则是纯拓扑排序。有‘=’,所以考虑把相等的人看成集合,同时把没有相等关系的个体也看成一个集合。然后利用并查集,对每个集合连边。所以要先用数组存下各关系先处理‘=’的集合,再连边,需要两个for循环。最后再来个拓扑排序。因为关系呈一条直线,所以拓扑队列中永远都只能有一个元素,若有多个元素,则有多个拓扑序列,题目所给信息不完全,输出‘UNCERTAIN’原创 2021-03-02 17:04:50 · 171 阅读 · 0 评论 -
每个环的边数(简单环)
2019CCPC秦皇岛F题(签到题)题意:在一个图中删除一些边后,使得不存在环,保证都是简单环(每条边至多只存在与一个环)。求方案数。思路:求每个环的边数,ans=(2^(每个环的边数)-1)*(2 ^(不在环上的边))方法1:用深度去算每个环的边数=deep[x]-deep[y]+1#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll mod=998244353;const int原创 2021-01-21 16:00:04 · 441 阅读 · 0 评论 -
二分图最大匹配(匈牙利)+字符串处理建边
2019CCPCF题题意:给定6个字符串,必须从每个字符串中取一个字符出来,若能构成harbin。则输出Yes,否则No思路:若,字符串A存在’h’,则将其与h点连边。其他情况同理。连号边后。问题转换成,找6条边,使得每条边的两端的点之间仅有这一条边。跑二分图最大匹配(匈牙利)即可。#include<bits/stdc++.h>using namespace std;const int maxn=1e3;int e,nex[maxn],to[maxn],head[maxn],k,原创 2021-01-18 23:08:40 · 79 阅读 · 0 评论 -
最大团(满足任意两点u->v || v->u,的最大子图)
洛谷UVA11324 The Largest Clique思路:有向图,先缩点,把每个SCC结点的权值赋为它的节点数。则问题转化为在DAG上求最大路径,可以dp求解。#include<bits/stdc++.h> using namespace std;const long long inf=0x3f3f3f3f;const long long maxn=1e5+5;int head[maxn],a[maxn],b[maxn],to[maxn],k1,n,m,w[maxn];in原创 2020-11-26 16:09:37 · 171 阅读 · 0 评论 -
缩点+LCA(倍增)//
逃不掉的路法一:缩点tarjan,LCA(倍增)树上两点距离 = deep( x )+deep( y )-2 * deep(LCA( x, y ))法二:求桥,然后dfs染色即可,至于缩点就是枚举每条边然后新建图。#include <bits/stdc++.h>using namespace std;const long long inf=0x3f3f3f3f;const long long maxn=2e5+5;int head[maxn<<1],q,a[maxn]原创 2020-11-06 17:11:58 · 149 阅读 · 0 评论 -
双连通分量
洛谷P2860 [USACO06JAN]Redundant Paths G边双连通分量定义:没有割边(删除任意一条边对图得连通性没有影响)扩展:图上任何两个点都有两种及以上不同路径互相到达板子题题意:缩点后的图是一棵树,在树中最少增加几条边,可以使树变为边双连通分量公式:增加边数 = (树中度为1的节点数 + 1)/ 2#include<bits/stdc++.h> using namespace std;const long long inf=0x3f3f3f3f;cons原创 2020-11-05 16:51:23 · 163 阅读 · 0 评论 -
第K短路
洛谷P2865次短路1.dist[ i ][ 0 ]表示到点 i 的最短路 , dist[ i ][ 1 ]表示到点 i 的次短路2.最短路更新:dist[ i ][ 0 ] > len(j) + val( j , i )次短路更新:dist[ i ][ 0 ] < len(j) + val( j , i ) < dist[ i ][ 1 ](len[j]表示从起点 s 到 j 点总距离)#include<bits/stdc++.h> using namesp原创 2020-11-04 22:35:25 · 76 阅读 · 0 评论 -
缩点tarjan + 最长路
洛谷P3387缩点在tarjan后进行缩点,把入度为0的点放进队列,再来个很朴实的最长路#include<bits/stdc++.h> using namespace std;const long long inf=0x3f3f3f3f;const long long maxn=1e6;int head[maxn],head2[maxn],num,k,k2,dis[maxn],in[maxn],mdis,to[maxn],to2[maxn],next[maxn],next2[maxn原创 2020-11-04 16:06:41 · 124 阅读 · 0 评论