vis

差分约束

对着背影说爱祢 提交于 2019-12-04 14:01:08
差分约束 如果有这样的条件 ​ x1-x2<=k1 ​ x1-x3<=k2 ​ x2-x3<=k3 转换过来就是 点1到点3最远为k1 其他点同理 那么要求点1到点n的距离 实际就是dis【n]=min(k2,k1+k3) 如果我们把式子1和式子3相加 就能得到x1-x3=k1+k3 那么这个问题就可以转换为最短路的问题: ​ 可以建立一个从点1到点2,点1到点3,点2到点3的一个又向图,然后我们再求其最大或最小距离。 现在看看例题 poj3169 题目大意: 有n个点 其中x条边为点a到点b的距离必选不大于c , 剩下的y条边点a到点b的距离必须不小c,求点1到点n的距离。 思路: ​ 在前x条边中,我们可以等到不等式 xa-xb<=c; ​ 在y条边中,我们得到不等式xa-xb>=c,我们对不等式两边同时乘以-1, 得到xb-xa<=-c,这样保证的了他们的不等于符号方向相同 然后就可应进行最短路的操作了。 代码: #include<string.h> #include<queue> using namespace std; const int maxn=1e4+4; struct node{ int from,to,w,next; }e[200000]; int head[maxn]; int vis[maxn]; int dis[maxn]; int cntt[maxn];

模板,最后挣扎一下

∥☆過路亽.° 提交于 2019-12-04 13:50:39
我不想退役,一定要拿省一 奥利给 1. 堆 #include<bits/stdc++.h> using namespace std; #define rint register int int n; priority_queue< int, vector< int >, greater< int > > que; inline int read( void ){ int re = 0, f = 1; char ch = getchar(); while( ch > '9' || ch < '0' ){ if( ch == '-' ) f = -1; ch = getchar(); } while( ch >= '0' && ch <= '9' ){ re = re * 10 + ch - '0'; ch = getchar(); } return re * f; } int main( void ){ n = read(); for( rint i = 1; i <= n; i++ ){ int temp; temp = read(); if( temp == 1 ) que.push( read() ); if( temp == 2 ) printf( "%d\n", que.top() ); if( temp == 3 ) que.pop(); } return 0; }

网络最大流 复习

眉间皱痕 提交于 2019-12-04 13:38:14
哎 打板子 调了 \(2\) h 无语了 \(EdmondKarp+Dinic(Dinitz)\) #include <set> #include <stack> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define reg register int #define isdigit(x) ('0' <= x&&x <= '9') template<typename T> inline T Read(T Type) { T x = 0,f = 1; char a = getchar(); while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();} while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();} return x * f; } const int MAXN = 10010,MAXM = 100010; int cnt,n,m,s,t,_ori[MAXN]; struct EDGE { int v,w,_nxt; EDGE() {v = w = _nxt

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

Spfa求负环

我只是一个虾纸丫 提交于 2019-12-04 11:48:08
简介 对于一个不存在负环的图,从起点到任意一个点最短距离经过的点最多只有 n 个。用 cnt[i] 表示从起点(假设是 1)到i的最短距离包含点的个数,初始化 cnt[1]=1,那么当我们能够用点u松弛点v时,松弛时同时更新cnt[v] = cnt[u]+1,若发现此时 cnt[v] > n,那么就存在负环 还有一种方法是记录每个点的入队次数,入队次数大于 n 就说明有负环,但是这样做一般都要比上面的方法慢。举个例子,在一个由 n 个点构成的负环中,这个方法要绕环n次,而上面的方法绕环 1 次就行了 例题 Luogu-P3385 模板题 第一种方案 #include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<map> #include<set> #include<cstring> #include<algorithm> #define lson x<<1 #define rson x<<1|1 #define ll long long #define rint register int #define mid ((L + R) >> 1) using namespace std; template <typename xxx> inline void read(xxx &x) { char

网络流24题 太空飞行计划问题

社会主义新天地 提交于 2019-12-04 10:39:19
题目传送门 这道题不是好久之前做的了 填一下网络流24题的坑 本质上是个最大权闭合图问题的模板 (话说这么多问题,我怎么记得住) 在源点 \(S\) 和每个实验之间连一条边权为实验利益的边 在每个实验和它需要的仪器之间连一条边权为 \(+\infty\) 的边 在仪器和汇点 \(t\) 之间连一条边权为仪器花费的边 然后跑最小割就好了 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define LL long long #define inf 0x7fffffff using namespace std; LL read() { LL k = 0, f = 1; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') k = k * 10 + c - 48, c = getchar(); return k * f; } struct zzz { int t, nex, len; }e[100010 << 1]; int head[1010], tot = 1; void

Educational Codeforces Round 56 Div. 2

喜你入骨 提交于 2019-12-04 10:33:31
比赛传送门 感觉这次 \(CF\) 的 \(C\) 题好简单,做出 \(3\) 道题+全部 \(AC\) ,涨了29分,摆脱 \(pupil\) ,指日可待! A.Dice Rollings 这道题最大的难度在理解题意上,只要输出合法的方案即可,所以不要想得太复杂。 我们可以发现,除了 \(0,1\) 以外,任何自然数都可以用 \(2,3\) 的和表示出来,那我们直接将点数除以2就好了,相当于我们我们只用 \(2,3\) 来投出那个数。 这么简单,代码就不放了。 B.Letters Rearranging 题意很简单,让你打乱一个字符串,使打乱后的字符串不为回文串,无解输出 \(-1\) 。 直接 \(sort\) 字符串,排完序再检查一遍是否为回文串(其实没必要单独再扫一遍,直接判断第一个字符和最后一个字符是否相等即可) #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; int read(){ int k=0,f=1; char c=getchar(); while(c<'0'||c>'9'){ if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9')

网络流24题 魔术球问题

浪子不回头ぞ 提交于 2019-12-04 10:28:10
题目传送门 又是一个神奇的建图题,建图 \(Van\) ♂全不会啊 大体就是我们一个一个的把球放进来,每放进来一个,我们就求出当前的最小路径覆盖数(当前顶点数-最大流),直到最小路径覆盖数 \({>}\) 柱子数。此时的球的编号 \(-1\) 就是第一问的答案。第二问就是求每一条路径,顺着推下来就好了 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<cmath> using namespace std; struct zzz{ int t,len,nex; }e[100010<<1]; int head[20010],tot=1; void add(int x,int y,int z){ e[++tot].t=y; e[tot].len=z; e[tot].nex=head[x]; head[x]=tot; } int s=0,t=20000,vis[20010],pre[20010]; bool bfs(){ memset(vis,0,sizeof(vis)); queue <int> q; q.push(s); vis[s]=1; while(!q.empty()){ int k=q.front(); q.pop(); for

线性筛的各种用处

我与影子孤独终老i 提交于 2019-12-04 10:24:52
线性筛筛质数: 1 int cnt, prime[N]; 2 bool vis[N]; 3 void getprime(int n) { 4 vis[0] = vis[1] = 1; 5 for (int i = 2; i <= n; i++) { 6 if (!vis[i]) { 7 prime[++cnt] = i; 8 } 9 for (int j = 1; j <= cnt && i * prime[j] <= n; j++) { 10 vis[i * prime[j]] = true; 11 if (i % prime[j] == 0) { 12 break; 13 } 14 } 15 } 16 } View Code 线性筛筛欧拉函数: 1 int cnt, prime[N], phi[N]; 2 bool vis[N]; 3 void getphi(int n) { 4 vis[0] = vis[1] = 1; 5 for (int i = 2; i <= n; i++) { 6 if (!vis[i]) { 7 prime[++cnt] = i; 8 phi[i] = i - 1; 9 } 10 for (int j = 1; j <= cnt && i * prime[j] <= n; j++) { 11 vis[i * prime[j]] = true; 12

洛谷 P2347 砝码称重

扶醉桌前 提交于 2019-12-04 09:29:32
题目传送门 解题思路: 找出所有在1000内可以用给出数据的表示的量,数一数一共有几个即为答案 AC代码: 1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 int a[7],v[] = {0,1,2,3,5,10,20},ans; 7 bool vis[1001]; 8 9 int main() { 10 for(int i = 1;i <= 6; i++) 11 scanf("%d",&a[i]); 12 vis[0] = 1; 13 for(int i = 1;i <= 6; i++) 14 for(int j = 1;j <= a[i]; j++) 15 for(int k = 1000;k >= 0; k--) 16 if(vis[k]) 17 vis[k+v[i]] = 1; 18 for(int i = 1;i <= 1000; i++) 19 if(vis[i]) ans++; 20 printf("Total=%d",ans); 21 22 return 0; 23 } //NOIP提高1996 T4 来源: https://www.cnblogs.com/lipeiyi520/p/11853646.html