vis

图论模板

南笙酒味 提交于 2019-11-27 20:36:04
一:最短路 1:Floyd void Floyd() { for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); } } } } View Code extend:Floyd求最小环 for(int i=1;i<=top;i++){ for(int j=1;j<=top;j++){ dis[i][j]=w[i][j]=INF; } } for(int i=1;i<=top;i++){ for(int j=i;j<=top;j++){ if(a[i]&a[j])dis[i][j]=dis[j][i]=w[i][j]=w[j][i]=1; if(i==j)dis[i][j]=w[i][j]=0; } } ll minn=INF; for(int k=1;k<=top;k++){ for(int i=1;i<k;i++){ for(int j=i+1;j<k;j++){ minn=min(minn,dis[i][j]+w[i][k]+w[k][j]); } } for(int i=1;i<=top;i++){ for(int j=1;j<=top;j++){ dis[i][j]=min(dis[i][j]

最短路

橙三吉。 提交于 2019-11-27 20:35:24
DJ算法: 基本概念; 通过松弛每一个点(当前距离最小的点)的距离来达到最短距离。  不过不能解决有负权边的问题(会无线循环)。 时间复杂度; O(n^2); (循环N次 每次在寻找N次的最小点 ,每次更新相邻点的时间忽略不计) 代码: //vis【】检查是否到达过这个点,dis为到达每个点的距离 void djj(int s) { memset(dis,0x3f,sizeof dis); dis[s]=0;vis[s]=1; for(i=1;i<=n;i++) //循环N次,每次找出最短路 { for(int j==0;j<mzy[s].size();j++) //更新相邻的点 { if(dis[j]<mzy[s].w+dis[s]) { dis[j]==mzy[s].w+dis[s]; } } //寻找距离最短的点 int bestt=0x3f; for(int j==1;j<=n;j++) { if(bestt>dis[j]&&vis[j]==0) { bestt=dis[j];s=j; } } vis[s]==1; } } DJ的优化: 优先队列: 基本操作: empty()    如果队列为空,则返回真 pop()    删除对顶元素,删除第一个元素 push()    加入一个元素 size()     返回优先队列中拥有的元素个数 top()    

并查集

拥有回忆 提交于 2019-11-27 19:13:20
一、鄙人的浅薄认知:给你一些具有父子关系的数据,你的任务就是把他们家家谱汇总出来,然后,顺便记录一些年龄啊,几个孩子什么的,最后回答问题就行了。 二、典型例题 1、HDU 1232 畅通工程 http://acm.hdu.edu.cn/showproblem.php?pid=1232 这道题是大多数人的入门题。 题解:有好多村子,现在已经建了一些路了,问还要建多少才能让所有的村子相通。 首先至少ans = n - 1条,如果目前互不认识。然后建立父子关系,不是一个祖宗的给他们建了路了,父子关系成立,他们成为一家子了,ans 自然 - 1。 是一个祖宗的本来就是一家子,不用管。然后一直这样判断直到读入结束。 代码: 1 #include<iostream> 2 #include<cstring> 3 #include<queue> 4 using namespace std; 5 const int N = 1010; 6 int father[N]; 7 8 int Find(int x) { 9 if (father[x] == x) return x; 10 return father[x] = Find(father[x]); 11 } 12 13 int main() 14 { 15 int n, m; 16 while (scanf("%d", &n) && n) {

noip模拟【20171102】

吃可爱长大的小学妹 提交于 2019-11-27 19:02:21
T1 [数学] 期望得分:100 先通分,求出分子的最小公倍数,再讨论跟共同的分母B*D的关系即可。 【code】 #include<bits/stdc++.h> using namespace std; #define ll long long #define File "tile" inline void file(){ freopen(File".in","r",stdin); freopen(File".out","w",stdout); } inline int read(){ int x = 0,f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){if(ch=='-')f = -1; ch = getchar();} while(ch >= '0' && ch <= '9'){x = (x<<1) + (x<<3) + ch-'0'; ch = getchar();} return x*f; } //const int mxn = ; int T,A,B,C,D; ll gcd(ll x,ll y){ return y ? gcd(y,x%y) : x; } int main(){ file(); T = read(); while(T--){ A = read(),B = read(),C = read()

HDU 4725(最短路+思维建图)

牧云@^-^@ 提交于 2019-11-27 18:41:05
题意:T组输入。n,m,c代表n个点,m个关系,相邻两层移动距离为C。每个点都会存在某一层上。   一个点可以移动c到相邻的层上任意一点(不能移动c到同一层的一点上)。 问:第一个点到第n个点的最短路 思路:把每层看做其他的新加的点,第一层可以看作第n+1个点。  ------------------------------------------------------------------------- 我刚开始写的时候。 错解:第一层的所有点和第n+1个点建了双向,且权值为零的路。这样是错的,因为如果这样建图,同一层的点互相达到的距离为0. 正解:由第n+1个点到第一层的所有点建个 单向 的路,再由第一层的各个点建个 单向 的路到第一层相邻的两个层(就是第零层和第二层,实际上没有第零层,举个例子而已, k层的两边是n+k+1和n+k-1 )的路,如果这层不存在就不需要建路。 注意第1层和第n层要特殊判断一下。 最短路跑完后如果d[n]==inf,侧代表无路 #include <iostream> #include <cmath> #include <cstdio> #include <cstring> #include <string> #include <map> #include <iomanip> #include <algorithm> #include

SP5150 JMFILTER - Junk-Mail Filte(并查集)

 ̄綄美尐妖づ 提交于 2019-11-27 18:36:24
直秒并查集。这题的难点就在于怎么删点。如果要删的是叶节点,那还好,直接刨掉即可 如果是中间节点甚至是根节点,那就不好办了..... solution: 对于独立一个点,我可以用邻接表模拟,然后用并查集维护联通,删点就是普通删点,但是实现难度高,复杂度大,算了,还是想正解吧 正解:对于一个删了的点,我们打个标记,然后开一个新点表示这个点(居然有点像主席树233.....) 于是, 动态开点并查集 诞生了(口胡) 具体操作在代码里解释 代码: #include<bits/stdc++.h> using namespace std; const int maxn=2e6+9; int n,m,ans,vis[maxn],fa[maxn],d[maxn],cnt; int T; int find(int x)//普普通通的并查集 { if(fa[x]==x) return x; return fa[x]=find(fa[x]); } void mergy(int x,int y)//普普通通的合并 { int fx=find(x); int fy=find(y); if(fx!=fy) fa[fx]=fy; } void del()//普普通通的清零(多组数据) { memset(vis,0,sizeof(vis)); ans=0; n=0,m=0; } int main() {

2-SAT入门

佐手、 提交于 2019-11-27 16:55:44
SAT是适定性(Satisfiability)问题的简称。一般形式为k-适定性问题,简称 k-SAT。而当$k>2$ 时该问题为NP完全的。所以我们只研究$k=2$时 情况。 定义 2-SAT,简单的说就是给出$n$ 个集合,每个集合有两个元素,已知若干个$\langle a, b \rangle$ ,表示$a$与$b$ 矛盾(其中$a$ 与$b$ 属于不同的集合)。从每个集合选择一个元素,使得选出的$n$ 个元素两两不矛盾的问题,就是2-SAT问题。显然可能有多种选择方案,一般题中只需要求出一种即可。 解决方法 我们考虑将2-SAT问题往图论的方向靠,每个元素用结点来表示,元素间的矛盾关系建边来表示。 设$\{a, a'\}$是一个集合里的元素,$\{b, b'\}$是另一个集合里的元素,假如$a,b$之间有矛盾,那么连边$a\to b'$,表示选了$a$就要选$b'$,连边$b\to a'$,表示选了$b'$就要选$a$。 这样问题就转化为了从$2\times n$个结点里选出$n$个分属不同集合的结点,并且对于每个选出的结点,其所有后继结点也都被选出。 方法1:dfs暴搜 就是沿着图上一条路径,如果一个点被选择了,那么这条路径以后的点都将被选择,那么,出现不可行的情况就是,存在一个集合中两者都被选择了。最坏时间复杂度为$O(nm)$,虽然后面讲的Tarjan

Tree-点分治

六月ゝ 毕业季﹏ 提交于 2019-11-27 16:07:30
题意: 求树上两点之间距离小于 k 有多少组。 解决必备条件: 树的重心求解 https://blog.csdn.net/flymoyu/article/details/99692889 点分治 https://blog.csdn.net/flymoyu/article/details/99693871 代码: # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> # include <vector> # include <queue> # include <set> # include <map> # include <string> # include <math.h> # include <stdlib.h> # include <time.h> using namespace std ; const int MAXN = 10010 ; const int INF = 0x3f3f3f3f ; struct Edge { int to , next , w ; } edge [ MAXN * 2 ] ; int head [ MAXN ] , tot ; void init ( ) { tot = 0 ; memset ( head , - 1 , sizeof

残缺的棋盘 (BFS)

流过昼夜 提交于 2019-11-27 15:54:06
在国际象棋里,王是最重要的一个棋子。每一步,王可以往上下左右或者对角线方向移动一步,如下图所示 给定两个格子 A(r1c1) B(r2c2),你的任务是计算出一个王从 A到 B至少需要走多少步。为了避免题目太简单,我们从棋盘里拿掉了一个格子 C(r3c3)(ABC保证互不相同),要求王从 A走到 B的过程中不能进入格子 C。在本题中,各行从上到下编号为 1~8,各列从左到右编号为1~8。 Input 输入包含不超过10000组数据。每组数据包含6个整数r1 c1 r2 c2 r3 c3 (1<=r1 c1 r2 c2 r3c3<=8). 三个格子A B C 保证各不相同。 Output 对于每组数据,输出测试点编号和最少步数。 Sample Input copy1 1 8 7 5 6 1 1 3 3 2 2 Sample Output copyCase 1: 7 Case 2: 3 #include <iostream> #include <algorithm> #include <cstdio> #include <string> #include <cstring> #include <cstdlib> #include <map> #include <vector> #include <set> #include <queue> #include <stack>

P2469 [SDOI2010]星际竞速

試著忘記壹切 提交于 2019-11-27 15:36:50
思路:最小费用最大流 提交: \(1\) 次 题解: 拆点 对于题目中的边 \((u,v)\) 且 \(u<v\) ,则连 \((u,v+n)\) ,流量为 \(1\) ,费用为边权。 对于能力爆发,连边 \((S,i+n)\) ,流量为 \(1\) ,费用为能力爆发的代价。 最大流一定会跑满(即边 \((i+n,T)\) 满流),代表所有点都只经过一遍。 \((S,i+n)\) 满流代表使用了能力爆发, \((u,v+n)\) 满流代表选择边 \((u,v)\) 。 #include<cstdio> #include<iostream> #include<cstring> #include<queue> #define ll long long #define R register int using namespace std; namespace Luitaryi { template<class I> inline I g(I& x) { x=0; register I f=1; register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f; do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f; } const int N=1610,M