图论

图论500题

岁酱吖の 提交于 2019-12-05 12:08:38
【HDU】 1213 How Many Tables 基础并查集★ 1272 小希的迷宫 基础并查集★ 1325&&poj1308 Is It A Tree? 基础并查集★ 1856 More is better 基础并查集★ 1102 Constructing Roads 基础最小生成树★ 1232 畅通工程 基础并查集★ 1233 还是畅通工程 基础最小生成树★ 1863 畅通工程 基础最小生成树★ 1875 畅通工程再续 基础最小生成树★ 1879 继续畅通工程 基础最小生成树★ 3371 Connect the Cities 简单最小生成树★ 1301 Jungle Roads 基础最小生成树★ 1162 Eddy's picture 基础最小生成树★ 1198 Farm Irrigation 基础最小生成树★ 1598 find the most comfortable road 枚举+最小生成树★★ 1811 Rank of Tetris 并查集+拓扑排序★★ 3926 Hand in Hand 同构图★ 3938 Portal 离线+并查集★★ 2489 Minimal Ratio Tree dfs枚举组合情况+最小生成树★ 4081 Qin Shi Huang's National Road System 最小生成树+DFS★★??? 4126 Genghis

0x60 图论

巧了我就是萌 提交于 2019-12-04 13:19:40
0x61 最短路 Dijkstra 最短路的经典做法之一,相比后面的 \(SPFA\) , \(Dij\) 的复杂度更低,更加的稳定 但是如果出现负环时, \(Dij\) 是不能用的 #include <bits/stdc++.h> #define PII pair< int , int > #define F first #define S second using namespace std; const int N = 10005 , M = 500005 , INF = 0x7f7f7f7f; int n , m , s ; int dis[N]; vector< PII > e[N]; bool vis[N]; set<PII> q; inline int read() { register int x = 0; register char ch = getchar(); while( ch < '0' || ch > '9' ) ch = getchar(); while( ch >= '0' && ch <= '9' ) { x = ( x << 3 ) + ( x << 1 ) + ch - '0'; ch = getchar(); } return x; } inline void add( int x , int y , int w ) { e[x].push

图论 - 最短路 - Floyd

邮差的信 提交于 2019-12-04 10:28:58
图论 - 最短路 - Floyd 题目链接: https://www.luogu.org/problem/P2910 代码: #include <bits/stdc++.h> using namespace std; const int N = 110; const int M = 10010; int n, m; int dis[N][N], ord[M]; void Floyd() { for (int k = 1; k <= n; k ++ ) { for (int i = 1; i <= n; i ++ ) { for (int j = 1; j <= n; j ++ ) { if (dis[i][j] > dis[i][k] + dis[k][j]) { dis[i][j] = dis[i][k] + dis[k][j]; } } } } } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; i ++ ) { scanf("%d", &ord[i]); } for (int i = 1; i <= n; i ++ ) { for (int j = 1; j <= n; j ++ ) { scanf("%d", &dis[i][j]); } } Floyd(); int ans = 0; for (int

模板 - 图论 - 强连通分量 - Kosaraju算法

浪尽此生 提交于 2019-12-04 09:45:56
这个算法是自己实现的Kosaraju算法,附带一个缩点,其实缩点这个跟Kosaraju算法没有什么关系,应该其他的强连通分量算法计算出每个点所属的强连通分量之后也可以这样缩点。 算法复杂度: Kosaraju算法:两次dfs,复杂度O(n+m) 强连通分量缩点算法:遍历每个点每条边,复杂度O(n+m) 对边排序去重:复杂度O(n+mlogm) namespace SCC { const int MAXN = 1e6 + 5; int n; vector<int> G[MAXN], BG[MAXN]; int c1[MAXN], cntc1; int c2[MAXN], cntc2; int s[MAXN], cnts; int n2; vector<int> V[MAXN]; vector<int> G2[MAXN], BG2[MAXN]; void init(int _n) { n = _n; cntc1 = 0, cntc2 = 0, cnts = 0; for(int i = 1; i <= n; ++i) { G[i].clear(); BG[i].clear(); c1[i] = 0; c2[i] = 0; s[i] = 0; V[i].clear(); G2[i].clear(); BG2[i].clear(); } } void add_edge(int u, int

2016 day1

自古美人都是妖i 提交于 2019-12-04 08:15:16
总: 有好多可得的部分分啊,但我也只是拿了20。。 我突然感觉我的图论学的好烂啊。。 1. 玩具谜题 emmm... 就是个模拟。。在找规律推推公式。。 2. 天天爱跑步 额...这个紫题为啥要放到第二题???(我默认为题目难度是递增的) 但还好我机智,最后两个直接看部分分 emm...然后还是只拿了20.。。。 3.换教室 这个,,上面说了我是把它当最难得看的, 而且,读了一遍题目后。。没懂。。 我又读了几遍。。嗷嗷~~好像懂了 又是图论的题。。。 图论弱鸡的我超绝望。。 看一下子任务,有n=1、m=0的情况,看起来很简单的样子。。但原谅我基础不好。。木有做出来 来源: https://www.cnblogs.com/aprincess/p/11847935.html

图论----最短路问题

南楼画角 提交于 2019-12-04 03:46:33
最短路问题有3种常用方法: Floyd,Dijkstra,SPFA 以下为总结代码(参考) Floyd 可求图中任意两点间的最短路 时间复杂度上有很大不足----O(N^3) 代码难度简单 #include<bits/stdc++.h> typedef long long ll; using namespace std; ll n,m,k; ll s[1005][1005]; int main() { memset(s,0x3f,sizeof(s)); scanf("%lld%lld%lld",&n,&m,&k); for(ll i=1;i<=m;i++) { ll x,y,z; scanf("%lld%lld%lld",&x,&y,&z); s[x][y]=min(s[x][y],z); } for(ll i=1;i<=n;i++) { s[i][i]=0; for(ll j=1;j<=n;j++) { s[j][j]=0; for(ll o=1;o<=n;o++) { s[o][o]=0; s[j][o]=min(s[j][o],s[j][i]+s[i][o]); } } } for(ll i=1;i<=k;i++) { ll b,e; scanf("%lld%lld",&b,&e); if(s[b][e]<=0x3f3f3f3f/2) printf("%lld\n",s[b]

图论 - 概念

蓝咒 提交于 2019-12-04 01:58:27
无序对: 对于二元集合{a,b},由于元素之间没有次序,称{a,b}为无序对,记为(a,b)。 有序对: 由两个元素x和y(允许x=y)按一定顺序排列成的二元组叫做一个有序对,记作<x,y>,其中x是它的第一元素,y是它的第二元素。 无序积: 设A,B为集合,则称{(a,b)| a∈A∧b∈B}为A与B的无序积,记为A&B。 恒有A&B=B&A。 笛卡尔积: 设A,B是任意两个集合,用A中元素作第一元素,B中元素作第二元素,构成的有序对,所有这样有序对的全体组成的集合称集合A和B的笛卡儿积,记作A×B。 顶点集: 非空集合V={v1,v2,…,vn},称为 图G 的顶点集(vertexset)V中元素称为顶点。 无向边: 是无序积V&V的一个多重子集E={e1,e2,…,en},称为的边集(edge set),E中的元素称为无向边,简称边。 无向图: 一个无向图是一个有序的二元组<V,E>,记作G, 即G=<V,E>。 每条边都是无向边的图称为无向图。 有向边: E为边集,是笛卡儿积V×V的多重子集,其元素称为有向边,简称边。 有向图: 一个有向图是一个有序的二元组<V,E>,记作D, 即D=<V,E>。 每条边都是有向边的图称为有向图。 基图: 将有向图各有向边均改成无向边后得到的无向图 称为原来有向图的基图(underlying graph)。 端点: 图G中的边e k

图论基础 [从入门到黑题]

情到浓时终转凉″ 提交于 2019-12-03 10:11:32
前言 楼主打模拟赛自闭就出来写blog了 本编blog目的是写一篇 全网最详细的 图论从基础到各种算法(在我会的范围,因此目前会不断更新)。 图 Q : 什么是图? A :在计算机科学里,图大概长这个样子(这是一张我随手画的图): 因此,图的 非正式 定义很简单,就是 有一些结点(node),有一些边(edge)将点连起来 。 我们可以形象的理解为 有若干个城市,每个城市间有一些道路相连,其中,城市就是结点,道路就是边。图就是整个城市群 (这个是最短路里常用的图论模型) 我们发现图就两个东西 : 结点 和 边 ,因此可以看见一些学术性的blog或百科里把图 抽象成 点集 \(V\) 和 边集 \(E\) (这里是集合知识,不知道不大要紧)。 因此,我们要 保存一个图 ,或 获得一个图的信息 ,就只要知道它的 结点与边 的情况即可。接下来我们从 结点 与 边 角度继续来了解图(下面还是基础知识,只要 了解,理解,留下印象 ) 有向图 与 无向图 这里是从边的角度来了解图 Q :什么是 有向图 和 无向图 ? A :这你得知道什么是 有向边 和 无向边 。 Q :那什么是 有向边 和 无向边 ? A : 上图是一条无向边,我们称这是一条由 1 到 2 的无向边,(标了 1 就是编号为 1 的结点)。边的一般形式是 \((u,v)\) , 所以这里就是 \((1,2)\) 在无向边里,

Day1T3小w的魔术扑克——图论

本小妞迷上赌 提交于 2019-12-03 04:24:18
为什么不搞 \(T2\) ??? 因为我太菜了,那题我是真的搞不出来 题目描述 链接: https://ac.nowcoder.com/acm/contest/1100/C 来源:牛客网 小 \(w\) 喜欢打牌,某天小 \(w\) 与 \(dogenya\) 在一起玩扑克牌,这种扑克牌的面值都在 \(1\) 到 \(n\) ,原本扑克牌只有一面,而小 \(w\) 手中的扑克牌是双面的魔术扑克(正反两面均有数字,可以随时进行切换),小 \(w\) 这个人就准备用它来出老千作弊。小 \(w\) 想要打出一些顺子,我们定义打出一个 \(l\) 到 \(r\) 的顺子需要面值为从 \(l\) 到 \(r\) 的卡牌各一张。小 \(w\) 想问问你,他能否利用手中的魔术卡牌打出这些顺子呢? 输入描述: 首先输入一行2个正整数 \(n\) , \(k\) ,表示牌面为 \(1\) ~ \(n\) ,小 \(w\) 手中有 \(k\) 张魔术扑克牌。 然后输入 \(k\) 行,每行两个数字,表示卡牌的正面和反面的面值。 接下来输入一行一个正整数 \(q\) ,表示 \(q\) 组查询,然后每组占一行查询输入两个整数 \(l\) , \(r\) 。表示查询小 \(w\) 能否打出这么一个 \(l\) 到 \(r\) 的顺子。 输出描述: 对于输出" \(Yes\) "表示可以," \(No\)

codeforces 1250N wires(简单图论)

ぃ、小莉子 提交于 2019-12-03 02:39:06
传送门 题意:给定n条边,连接编号从1到1e9之间的点,一次操作可以改变一条边连接的一个端点到另一个端点,也就是将第i条边(u,v)变成(u,w),v≠w,问最少次数操作使得这张图的所有边联通,输出操作次数k,以及每次操作的i,v,w。 分析:先将点离散化。假设有n个联通块s1,s2....sn,可以将连通块si内一条边端点改成si+1内一个点,但是改变这条边不能使得原有的连通块内的边变得不连通。dfs这个连通块最后一个被访问的边就是满足要求的边。 代码: #include <bits/stdc++.h> #define mp make_pair #define debug(x) cout << #x << ": " << x << endl #define pb push_back typedef long long LL; const int maxn = 4e5 + 10; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; using namespace std; typedef pair<int, int> p; p e[maxn], tail[maxn]; int val[maxn], len = 0, n, t, ord[maxn], vis[maxn], tot = 0, head[maxn]