dis

差分约束

眉间皱痕 提交于 2020-02-02 21:51:39
差分约束 hhh,这几天病毒感染,真的不敢乱溜达,干脆狂写blog算了,hhh 一般形式 差分约束题一般是给出大量的一些不等式 a i − b i ≤ x → a i ≤ x + b i a_i-b_i\leq x \rightarrow a_i\leq x + b_i a i ​ − b i ​ ≤ x → a i ​ ≤ x + b i ​ 由上面这个不等式我们应该可以联想到最短路的不等式 d i s [ u ] ≤ d i s [ v ] + x ( u → v ) dis[u]\leq dis[v] + x(u \rightarrow v) d i s [ u ] ≤ d i s [ v ] + x ( u → v ) 因此,我们可以将差分约束化成一个最短路来求,我们的 d i s [ u ] dis[u] d i s [ u ] 保存由远点到 u u u 的可以选择的最大范围! 为什么是最大范围? 我们每一次选择的是 m i n ( u → v ) min(u \rightarrow v) m i n ( u → v ) ,那么一开始我们就会选择一个从原点 s s s 出发的最小范围,且没有其他路径会使她变得更小(三角形),那么这个由原点出发的长度将会是 s → u s \rightarrow u s → u 的范围,选择最大的话,就是这个范围啦。 求最长路

【数据结构】图

痞子三分冷 提交于 2020-02-02 04:58:40
【数据结构】图 图的存储 //邻接矩阵,即开一个二维数组 vector<int>Adj[N]; //邻接表 struct Node{ int v; //边的终点编号 int w; //边的权值 }; vector<Node>Adj[N]; //有顶点1到顶点3的边,权值为4: Node temp; temp.v=3; temp.w=4; Adj[1].push_back(temp);//通过定义一个临时变量的方式,添加边 //有顶点1到顶点3的边,权值为4: struct Node{ int v; int w; Node(int _v,int _w) :v(_v) ,w(_w) {} //默认构造函数 } Adj[1].push_back(Node(3,4));//不需要构造临时变量 图的遍历 const int maxv=1001; //最大顶点数 const int INF=1000000; //很大的一个数,来表示,在有向图中,两顶点之间不连通 深度优先遍历 //邻接矩阵版 int n; //n为顶点数 int G[maxn][maxn]; bool vis[maxn]={false}; void dfs(int u,int depth){ //u为当前访问的顶点编号,depth为深度 vis[u]=true; for(int v=0;v<n;v++){ if(vis[v]=

PAT Travel Plan(dijkstra应用)

泄露秘密 提交于 2020-01-20 00:35:00
简介: 写这道题的时候思路很清晰,毕竟只是套个模板。 思路: Dijkstra 算法直接用就行。第一遍提交就AC了,果然c++做算法题比Java好用太多了(~ ̄▽ ̄)~ PS: 具体请看注释(好久没写这么多注释了(‾◡◝) #include <bits/stdc++.h> //这个库包了目前c++所有的头文件。 #define INF 0x3f3f3f3f //设置无穷大 using namespace std; int n,m,s,d; struct node{ int dis,cos; }city[505][505];//结构体存储路径,花费. bool vis[505];// 节点是否被访问过 int cost[505],dist[505],path[505];//记录从起点到每个节点的花费,路径长度,path数组以前驱记录的形式记忆路径。 int main() { scanf("%d %d %d %d",&n,&m,&s,&d); for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ city[i][j].dis = i == j ? 0 : INF; city[i][j].cos = i == j ? 0 : INF; } }//初始化每个节点的数据,INF即初始每个节点之间都是不可达的,花费也无穷大。 int w,v

AGC31E Snuke the Phantom Thief

感情迁移 提交于 2020-01-17 09:00:08
Snuke the Phantom Thief 有 \(N\) 个珠宝,第 \(i\) 个位于 \((x_i, y_i)\) ,价值为 \(v_i\) 。你可以选择一些珠宝,有若干限制,每个限制形如如下四种之一: \(x ≤ a_i\) 的珠宝只能选择不超过 \(b_i\) 个; \(x ≥ a_i\) 的珠宝只能选择不超过 \(b_i\) 个; \(y ≤ a_i\) 的珠宝只能选择不超过 \(b_i\) 个; \(y ≥ a_i\) 的珠宝只能选择不超过 \(b_i\) 个; 最大化选择的总价值。 \(1 ≤ N ≤ 80,1 ≤ x_i, y_i, a_i≤ 100\) 。 题解 https://www.cnblogs.com/zhoushuyu/p/10548483.html 首先这数据范围看着就很费用流 先考虑一维怎么做。 一个很妙的转化是:限制横坐标 \(≤a_i\) 的珠宝里至多选 \(b_i\) 个,等价于选择的横坐标第 \(b_{i+1}\) 小的珠宝,其横坐标必须 \(>a_i\) 。 如果是限制横坐标 \(≥a_i\) 的珠宝至多选 \(b_i\) 个,则可以先枚举选 \(s\) 个珠宝,然后限制就等价于选择的第 \(s-b_i\) 个珠宝其横坐标必须 \(<a_i\) 。(前述只考虑 \(b_i < s\) 的限制, \(b_i ≥ s\) 的限制显然无效)

[SCOI2010]传送带

夙愿已清 提交于 2020-01-16 23:41:14
嘟嘟嘟 首先令E点表示在E点离开传送带AB,F点表示在F点上传送带CD,则总用时为:dis(A, E) / p + dis(E, F) / r + dis(F, D) / q。然而这是一个有两个变量的函数。于是有一个不错的方法:把E成参数,然后就变成了一个形如f(x) = √(t 2 + x 2 ) - x的函数,虽然我证不出来是一个单峰函数,但是几何画板告诉我是。于是我们可以三分求F。至于E,再三分求。 所以说,这是一道二维的三分套三分的题,三分求E,假设E已知的情况下三分求F。 代码很好懂。 1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a, x) memset(a, x, sizeof(a)) 15 #define rg register 16

Charles in Charge Gym - 101490E (队列优化dij+二分)

三世轮回 提交于 2020-01-11 19:53:46
https://vjudge.net/contest/350975#problem/E 题意:给一张无向图,求一条从1到n路上的最大边,使得其最小,同时还要满足 这条路长度<=最短路*(1+X%) 先跑一边最短路,求出最短路 然后二分答案,求在最大边为mid的情况下的最短路(在松弛的时候判断一下边大于mid就不松弛),用spfa T了, 得用队列优化dij #include<bits/stdc++.h> using namespace std; const long long maxn = 100009; typedef pair<long long,long long > pii; struct node { long long to,next; double w; } edge[maxn<<1]; double per,minn,tot; long long ans; long long head[maxn<<1],flag[maxn],n,cnt,dis[maxn]; void add(long long u,long long v,double w) { edge[cnt].w = w; edge[cnt].to = v; edge[cnt].next = head[u]; head[u] = cnt ++; } long long dij(long long s,long

poj 1860 Currency Exchange SPFA

こ雲淡風輕ζ 提交于 2019-12-30 05:04:50
算法: 1.SPFA求最长路,dis【】初始直为0,大于改成小于号 2.松弛结束后,判断是否大于dis[S] > V, 大于就输出YES, 否则输出NO View Code #include <stdio.h> #include <string.h> #include <stdlib.h> #include <queue> #include <math.h> #include <algorithm> #define MAXN 100100 using namespace std; struct Edge { int u, next; double val, cost; Edge( ) { } Edge( int U, int Next, double Val, double Cost): u(U), next(Next), val(Val), cost(Cost) {} }edge[MAXN]; int N, M, S, head[MAXN], visit[MAXN], hash[MAXN], size; double V, dis[MAXN]; struct node { int ID; // double rate; double money; // double c; }; void init( ) { for( int i = 0; i < MAXN; i++) {

周更1(最短路)

三世轮回 提交于 2019-12-29 02:23:04
1、 POJ - 1062 昂贵的聘礼 题意:你想娶酋长的女儿,但酋长要求你给一定数额金钱的聘礼。除了金钱外,酋长也允许你用部落里其他人的某物品加上一点钱作为聘礼。而其他人的物品也可以通过指定的另外一些人的某物品加上一些金钱获得。部落里的每个人有一个等级。你的整个交易过程涉及的人的等级只能在一个限定的差值内。问你最少需要多少金钱才能娶到酋长女儿。假定每个人只有一个物品。 思路:对冒险者的等级进行枚举,冒险者只能和在他等级以上的人进行交易。这样枚举的好处是能够把所有的情况都考虑进去。 1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 using namespace std; 5 6 const int INF=0x3f3f3f3f; 7 int map[200][200],n,m; 8 int vis[2000100],dis[1001000],sum=0; 9 int rankk[100100],val[1010000]; 10 11 int check(int x) 12 { 13 if(rankk[x]>=rankk[0]&&rankk[x]-rankk[0]<=m||m==0) return true; 14 return false; 15 16 } 17 18 int dijkstra()

【学习】点分治

元气小坏坏 提交于 2019-12-27 06:37:42
点分治是一种基于分治的算法 整体思想为不断删根把一棵较大的树拆成n个小树再分别求解再合并 关于此题 我们先随意指定一个根,树上路径就分成了过根的和不过根在一个子树里的 这样经过根的路径即为dis[u]+dis[v],dis[i]是i到根的路径长度 不经过根的就再找这棵子树的根如此递归 显然分治 把一个无根树转化为有根树,找重心 void getrt(int u,int fa){//找根 sz[u]=1;maxp[u]=0; for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(v==fa||vis[v])continue; getrt(v,u); sz[u]+=sz[v]; maxp[u]=max(maxp[u],sz[v]); } maxp[u]=max(maxp[u],sum-sz[u]); if(maxp[u]<maxp[rt])rt=u; } 找重心的意义在于每次选取子树的重心为子树的树根进行处理, 这样总的递归深度不会超过 l o g N层 以保证复杂度 预处理 void calc(int u){ int p=0; for(int i=head[u];i;i=e[i].nxt){ int v=e[i].to; if(vis[v])continue; rem[0]=0; dis[v]=e[i].w; getdis(v,u);/

【线性规划和网络流24题】

六月ゝ 毕业季﹏ 提交于 2019-12-27 03:26:08
(1)飞行员配对方案问题:二分图最大匹配。 思路:略。 View Code 1 #include<cstdio> 2 #include<cstring> 3 #define MAXN 1010 4 int cx[MAXN], cy[MAXN]; 5 int first[MAXN], next[MAXN], v[MAXN], e; 6 bool vis[MAXN]; 7 inline void addEdge(int x, int y) { 8 v[e] = y; 9 next[e] = first[x]; 10 first[x] = e++; 11 } 12 int path(int x) { 13 int i; 14 int y; 15 for (i = first[x]; i != -1; i = next[i]) { 16 y = v[i]; 17 if (!vis[y]) { 18 vis[y] = true; 19 if (cy[y] == -1 || path(cy[y])) { 20 cx[x] = y; 21 cy[y] = x; 22 return 1; 23 } 24 } 25 } 26 return 0; 27 } 28 int main() { 29 int n, m; 30 int i; 31 int x, y; 32 int ans; 33 while