dis

负环

允我心安 提交于 2019-11-29 04:57:12
#include<bits/stdc++.h> using namespace std; struct edge { int to,len,next; }edge[2000000]; long long n,m,s,num,tim[2000000],head[2000000],book[2000000],dis[2000000],b[20000000]; priority_queue<pair<long long,long long> > q; void sett() { n=m=s=num=0; memset(tim,0,sizeof(tim)); memset(book,0,sizeof(book)); memset(head,0,sizeof(head)); } void add(long long u,long long v,long long w) { edge[++num].to=v; edge[num].len=w; edge[num].next=head[u]; head[u]=num; } bool spfa(long long s) { long long h=1,t=1; for(long long i=1;i<=n;i++) dis[i]=2147483647; dis[s]=0; book[s]=1; b[t++]=s; tim[s]++; while(h

GZOI 2019 旅行者

浪子不回头ぞ 提交于 2019-11-29 03:28:26
Description 给你 \(n\) 个点 \(m\) 条边的有向图,求给定 \(k\) 个特殊点两两之间最短路的最小值。 \(T\) 组询问。 \(1 \leq T \leq 5\) \(1 \leq k \leq n \leq 10^5\) \(1 \leq m \leq 5 \times 10^5\) \(1 \leq z \leq 2 \times 10^9\) Solution 两种思路。 第一种: 对于每一条边 \((x,y,z)\) ,离 \(x\) 最近的特殊点是 \(a\) ,离 \(y\) 最近的特殊点是 \(b\) 。那么,这两个特殊点的距离是 \(dis_a + dis_b + z\) 。我们要找到最小值。 因为这是有向图,所以正反跑两次 Dijkstra 就可以了进行染色就可以了,染色是记录离每个城市最近的感兴趣的城市。如果 \(a = b\) ,那么就相当于走了一个环,所以我们要特判。 复杂度 \(O(T \times nlogn)\) 。 第二种: 将所有的点分成两个集合 \(A\) 和 \(B\) 。我们用源点 \(s\) 连接集合 \(A\) 中所有的点,边权都为 \(0\) ,再将集合 \(B\) 连向汇点 \(t\) ,边权都为 \(0\) 。集合内部边权不变。 将所有节点分成两个集合,要满足任何两个特殊点都有至少一次被分进了不同的集合

loj2090. 「ZJOI2016」旅行者

余生颓废 提交于 2019-11-28 11:03:18
loj2090. 「ZJOI2016」旅行者 链接 loj 思路 \((l,mid)(mid+1,r)\) .考虑跨过mid的贡献。 假设选的中间那条线的点为gzy,贡献为 \(dis(x,gzy)+dis(gzy,y)\) 那就计算n遍最短路,一次分治为 \(n^2mlog{nm}\) 设S=n*m.矩阵的长度是不定的,每次取最长的边进行分治是最好的,n最坏为 \(\sqrt{n}\) 。 \(f(n)=2*f(\frac{n}{2})+S\sqrt{S}logS。所以总的复杂度就是\) \(S\sqrt{S}logS\) 都在同侧的也需要跨一跨 代码 #include <bits/stdc++.h> #define FOR(i,a,b) for(int i=a;i<=b;++i) using namespace std; const int _=1e5+7,INF=0x3f3f3f3f; int read() { int x=0,f=1;char s=getchar(); for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1; for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0'; return x*f; } int n,m,q,ans[_],vis[_]; struct node { int x,y

【洛谷P1186】玛丽卡

≯℡__Kan透↙ 提交于 2019-11-28 07:20:33
Description 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。 在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。 麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。 玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。 编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。 Solution 找出在一条边断掉的情况下的单源最短路径,并输出最坏的情况(去边不同会影响最短路)。 完了??? 完了。。。 所以思路就出来了:一一去掉所有边,分别去求最短路。 仔细想想:时间复杂度(Dijkstra)O(n^2*m) 如果是dalao写带堆优化的也会到 O(nlogn*m) 但是! 时间复杂度实在是太高了!!! 怎么办??? 不慌, 慌也没用 。 我们不是分析过题吗?去掉一条边的单源最短路。如果去的边不是不删边情况下的单源最短路径上的边,那么会对最终答案有影响吗? 没有! 所以

Luogu P4943 密室 题解

白昼怎懂夜的黑 提交于 2019-11-28 02:38:38
闲扯 这是紫题?? 做了昨天讲课听了一天的网络流,脑子都痛了,换点题做,结果随机调到这道题,发现貌似很好做的样子。。 Solution 首先我们分情况讨论一下。 罗恩去密室 \(1\) ,哈利去密室 \(2\) 。 罗恩去密室 \(2\) ,哈利去密室 \(1\) 。 罗恩吃瓜,哈利去两个密室。 对于罗恩可以走的路,哈利一定是可以走的,所以哈利到两个密室的时间一定不小于罗恩。所以罗恩选择去他能去的密室中较近的一个,剩下一个由哈利去。 为什么是对哒? 考虑罗恩去较远的一个,那么哈利到较近的一个密室所用的时间是不大于罗恩所用时间的,所以答案为罗恩到较远密室所用的时间。 考虑罗恩去较近的一个,那么哈利到较远的一个密室所用的时间是不大于罗恩所用时间的,所以答案不大于罗恩到较远密室所用的时间。 综上,对于前两种情况,可以由以上策略解决。 对于第 \(3\) 种情况,我们记录一下哈利到两间密室用时最短为多少,再找出两间密室间的最小距离,两者累加即为答案。 最后输出再取一个最小值即可。 \(ps:\) 对于前两种情况,答案应取用两人用时的最大值。 Code #include<bits/stdc++.h> #define del(a,i) memset(a,i,sizeof(a)) #define ll long long #define inl inline #define il inl

AcWing 黑暗城堡

孤人 提交于 2019-11-28 01:44:42
AcWing 黑暗城堡 Description 在顺利攻破Lord lsp的防线之后,lqr一行人来到了Lord lsp的城堡下方。 Lord lsp黑化之后虽然拥有了强大的超能力,能够用意念力制造建筑物,但是智商水平却没怎么增加。 现在lqr已经搞清楚黑暗城堡有N个房间,M条可以制造的双向通道,以及每条通道的长度。 lqr深知Lord lsp的想法,为了避免每次都要琢磨两个房间之间的最短路径,Lord lsp一定会把城堡修建成 树形 的。 但是,为了尽量提高自己的移动效率,Lord lsp一定会使得城堡满足下面的条件: 设 D[i] 为如果所有的通道都被修建,第 i 号房间与第1号房间的最短路径长度;而 S[i] 为实际修建的树形城堡中第 i 号房间与第1号房间的路径长度;要求对于所有整数 i,有 S[i]=D[i] 成立。 为了打败Lord lsp,lqr想知道有多少种不同的城堡修建方案。 你需要输出答案对 2 ^ 31–1 取模之后的结果。 Input 第一行有两个整数 N 和 M。 之后 M 行,每行三个整数X,Y 和L,表示可以修建 X 和 Y 之间的一条长度为 L 的通道。 Output 一个整数,表示答案对 2 ^ 31–1 取模之后的结果。 Sample Input 3 3 1 2 2 1 3 1 2 3 1 Sample Output 2 题解: 题解来自mzx

AcWing 观光之旅

时光毁灭记忆、已成空白 提交于 2019-11-27 21:32:45
AcWing 观光之旅 Description 给定一张无向图,求图中一个至少包含3个点的环,环上的节点不重复,并且环上的边的长度之和最小。 该问题称为无向图的最小环问题。 你需要输出最小环的方案,若最小环不唯一,输出任意一个均可。 Input 第一行包含两个整数N和M,表示无向图有N个点,M条边。 接下来M行,每行包含三个整数u,v,l,表示点u和点v之间有一条边,边长为l。 Output 输出占一行,包含最小环的所有节点(按顺序输出),如果不存在则输出’No solution.’。 Sample Input 5 7 1 4 1 1 3 300 3 1 10 1 2 16 2 3 100 2 5 15 5 3 20 Sample Output 1 3 5 2 Data Size 1≤N≤100, 1≤M≤10000, 1≤l<500 题解: Floyd。 无向图求最小环用Floyd,有向图求最小环用Dijkstra。 我们知道,当Floyd做最短路时,枚举到k时,dis(i, j)表示的是i到j的最短距离 (途中只走小于k的点) 。那么我们就可以以k为环的中心。然后枚举两个点i, j表示k的左边点和右边点。那么这个环的权值就是dis(i, j) + a(i, k) + a(i, j),因为dis(i, j)能算出来是通过只走<k的点走出来的。所以i到j的最短路并没有与i ->

Luogu P4014 分配问题 题解

孤街醉人 提交于 2019-11-27 16:28:07
闲扯 蒟蒻的第一道自己想出怎么建图的题!! 虽然是一个没什么技术含量的图 想了想,还是写篇题解纪念一下。 题面 题面 Solution 要求最小费用和最大费用,同时限制了流量,考虑费用流。 虚拟一个超级源点,从这个点分别向 \(N\) 个任务连一条流量为 \(1\) ,费用为 \(0\) 的边。 虚拟一个超级汇点,才从 \(N\) 个物品分别向该点连一条流量为 \(1\) ,费用为 \(0\) 的边。 因为每个人只能做一件,且每个工作只能做一次,所以连的边流量都为一。而第 \(i\) 个人做第 \(j\) 个任务获得的贡献为 \(val_{i,j}\) ,所以从第 \(j\) 个物品向第 \(i\) 个人连一条费用为 \(val_{i,j}\) 的边。 如果是求最小费用最大流,那么直接跑模板。 如果是求最大费用最大流,只需要连边时将费用换为负数,求一个最小费用最大流,然后答案再取一个相反数即可。(这个处理好秒啊,自己没想出来,还是看了题解) Code #include<bits/stdc++.h> #define del(a,i) memset(a,i,sizeof(a)) #define ll long long #define inl inline #define il inl void #define it inl int #define ill inl ll #define

P1772 [ZJOI2006]物流运输

流过昼夜 提交于 2019-11-27 08:29:14
${\color{cyan}{>>Question}}$ 上古省选 最短路+$dp$ 先预处理出第$i$天到第$j$天的最短路长度(在限制条件下的),然后就是一个标准的一维多段$dp$ 令$f[i]$表示前$i$天的最小花费,只需枚举前一段的结尾$j$(即$j+1$到$i$的最短路是一样的) 有$$f[i] = min\left \{ f[j]+(i-j)*low[j+1][i]+k \right \}$$ $low[j+1][i]$表示第$i$天到第$j$天的最短路长度 上代码 1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #define ll long long 7 using namespace std; 8 9 template <typename T> void in(T &x) { 10 x = 0; T f = 1; char ch = getchar(); 11 while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();} 12 while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();

DP&图论 DAY 6 下午 考试

懵懂的女人 提交于 2019-11-27 00:45:17
DP&图论 DAY 6 下午 考试 3 5 10 3 1 3 437 1 2 282 1 5 328 1 2 519 1 2 990 2 3 837 2 4 267 2 3 502 3 5 613 4 5 132 1 3 4 10 13 4 1 6 484 1 3 342 2 3 695 2 3 791 2 8 974 3 9 526 4 9 584 4 7 550 5 9 914 6 7 444 6 8 779 6 10 350 8 8 394 9 10 3 7 10 9 4 1 2 330 1 3 374 1 6 194 2 4 395 2 5 970 2 10 117 3 8 209 4 9 253 5 7 864 8 5 10 6 样例输入 437 526 641 样例输出 题解 >50 pt dij 跑暴力 (Floyd太慢了QWQ O(n^3)) 枚举每个点作为起点,dijkstra,跑暴力 O( (n+m)logn ),寻找全局最短路 #include<iostream> #include<cstdio> #include<string> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<queue> using namespace std; inline