luogu P1710 地铁涨价
嘟嘟嘟
一道最短路好题。
首先明确一点,把一条边的边权变成2,等于删去这条边。因为变成2后最短路肯定不会经过这条边,就相当于删去这条边了。
所以题目变成了依次删去Q条边,求每一次删完边后有几个点的最短路变大了。
多做做题就会有这么个思维:删边不好办,然而逆向加边方便多了。所以30做法就是离线逆向加边,跑Q次dijkstra。时间复杂度(Qnlogn)。
正解是基于这个暴力的:想想dijkstra更新最短路的时候,如果成功从u更新了dis[v],那么前提一定是dis[u]已经是最短路。所以每一次我们可以不跑dijkstra,只用判断加的边(x, y)中,当前距离dis2[x]或是dis2[y]是否已经成为了最短路,如果是,就从这个点开始尝试更新他能走到的点的最短路(bfs, dfs都行,实测dfs更快)。然后如果到一个点的距离变成了最短路,ans--。
然后就是代码细节了:因为Q <= m,所以有一些边没删去,所以事先要加上,加边的时候不要每一次都判断dis2[x]或dis2[y]是否成为了最短路,而是在循环外面直接从1号节点更新,因为只有1号结点延伸出去的才可能成为最短路。而要是每一都判断dfs的话,虽然dfs会马上退出来,然而如果是一个菊花图的话,对于1号结点,每一次都遍历了很多条边,时间复杂度达到O(n2)。(这也就是我第7个点为啥一直TLE的原因……)
还有就是dis2实际上用一个bool数组就够,标记过就表示这个点已经成为了最短路,不用记录他的距离。
![](/assets/blank.gif)
![](/assets/blank.gif)
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 typedef long long ll; 17 typedef double db; 18 const int INF = 0x3f3f3f3f; 19 const db eps = 1e-8; 20 const int maxn = 1e5 + 5; 21 inline ll read() 22 { 23 ll ans = 0; 24 char ch = getchar(), last = ' '; 25 while(!isdigit(ch)) {last = ch; ch = getchar();} 26 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 27 if(last == '-') ans = -ans; 28 return ans; 29 } 30 inline void write(ll x) 31 { 32 if(x < 0) x = -x, putchar('-'); 33 if(x >= 10) write(x / 10); 34 putchar(x % 10 + '0'); 35 } 36 37 int n, m, q; 38 struct Edge 39 { 40 int nxt, to; 41 }e[maxn << 2]; 42 int head[maxn], ecnt; 43 void add(int x, int y) 44 { 45 e[++ecnt] = (Edge){head[x], y}; 46 head[x] = ecnt; 47 } 48 49 struct Node 50 { 51 int x, y; 52 }egs[maxn << 1]; 53 54 #define pr pair<int, int> 55 #define mp make_pair 56 bool in[maxn]; 57 int dis[maxn]; 58 void dijkstra(int s) 59 { 60 Mem(dis, 0x3f); 61 dis[s] = 0; 62 priority_queue<pr, vector<pr>, greater<pr> > q; 63 q.push(mp(dis[s], s)); 64 while(!q.empty()) 65 { 66 int now = q.top().second; q.pop(); 67 if(in[now]) continue; 68 in[now] = 1; 69 for(int i = head[now]; i != -1; i = e[i].nxt) 70 { 71 if(dis[e[i].to] > dis[now] + 1) 72 { 73 dis[e[i].to] = dis[now] + 1; 74 q.push(mp(dis[e[i].to], e[i].to)); 75 } 76 } 77 } 78 } 79 80 bool vis[maxn << 1]; 81 int a[maxn << 1], ans[maxn << 1], num; 82 83 void solve(int now, int d) 84 { 85 for(int i = head[now]; i != -1; i = e[i].nxt) 86 { 87 if(!vis[e[i].to] && d + 1 == dis[e[i].to]) 88 { 89 num--; 90 vis[e[i].to] = 1; 91 solve(e[i].to, d + 1); 92 } 93 } 94 } 95 96 int main() 97 { 98 Mem(head, -1); ecnt = -1; 99 n = read(); m = read(); q = read(); 100 for(rg int i = 1; i <= m; ++i) 101 { 102 egs[i].x = read(); egs[i].y = read(); 103 add(egs[i].x, egs[i].y); add(egs[i].y, egs[i].x); 104 } 105 dijkstra(1); 106 for(rg int i = 1; i <= q; ++i) a[i] = read(), vis[a[i]] = 1; 107 Mem(head, -1); ecnt = -1; 108 num = n - 1; 109 for(int i = 1; i <= m; ++i) if(!vis[i]) 110 { 111 int x = egs[i].x, y = egs[i].y; 112 add(x, y); add(y, x); 113 } 114 Mem(vis, 0); vis[1] = 1; 115 solve(1, 0); 116 for(rg int i = q; i; --i) 117 { 118 ans[i] = num; 119 int x = egs[a[i]].x, y = egs[a[i]].y; 120 add(x, y); add(y, x); 121 if(vis[x]) solve(x, dis[x]); 122 if(vis[y]) solve(y, dis[y]); 123 } 124 for(rg int i = 1; i <= q; ++i) write(ans[i]), enter; 125 return 0; 126 }
View Code
转载于:https://www.cnblogs.com/mrclr/p/9847670.html
luogu P1710 地铁涨价相关推荐
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
- 洛谷 P1710 地铁涨价 (dfs+bfs)
地铁涨价 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地铁连接两个不同的站. 地铁计 ...
- 洛谷 P1710 地铁涨价
题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...
- 洛谷P1710地铁涨价
题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...
- P1710 地铁涨价
题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...
- 题目 - 北京地铁 描述 北京地铁涨价了,现在的地铁票价计算方法如下: 6公里内 3元 (包括6公里) 6-12 公里 4元 (不包括6公里,包括12公里) 12-32 公里 每10公里加1元
题目 - 北京地铁 描述 北京地铁涨价了,现在的地铁票价计算方法如下: 6公里内 3元 (包括6公里) 6-12 公里 4元 (不包括6公里,包括12公里) 12-32 公里 每10公里加1元(不包括 ...
- 【洛谷 P1710】地铁涨价(dfs+bfs)
[题解][BFS+dfs] [图论题] [通过分析题目,我们可得知改变边权实际就是在删边.那么,如果每次删一条边,那么就要重新跑最短路,这样必然会T] [考虑离线处理,改删边位加边,看每次加一条边,有 ...
- 洛谷1710 地铁涨价
题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...
- [luogu1710]地铁涨价(bfs)
题目描述 传送门 题解 转化问题 这里路线涨价明显等同于删边,所以我们可以把问题倒过来思考: 图上依次(倒序)加边,问每个点成为最终图最短路的时间 分析 记原图的点1到达点i的最短路为dis[i],当 ...
最新文章
- 对order by的理解
- tensorflow1.14.0 包含了1.x和2.x内容,此后版本要求兼容该版本
- 20162311 算法复杂度-3
- 易宝典——玩转O365中的EXO服务 之四十 创建就地电子数据展示搜索
- Cambridge partner
- 天平游码读数例题_初二上册物理实验——托盘天平使用的注意事项
- Java并发编程(01):线程的创建方式,状态周期管理
- docker容器内漏洞_如何在2020年发现和修复Docker容器漏洞
- 存储过程,游标和触发器实例
- c语言warning scanf,【C】将m~n之间的素数输出与VS2005以上版本对C语言的scanf的警告warning C4996...
- 提高工作沟通技巧,加强沟通,不要推测他人发生问题发生的原因
- bzoj 2560: 串珠子【状压dp】
- 吟诗作赋不能赚钱,作诗的AI机器人的盈利之路在哪
- 宝塔面板FTP存储空间无法连接的问题
- 游戏开发工程师岗位要求
- 保护眼睛android版本,夜间护眼软件下载-夜间护眼 安卓版v4.9.1-PC6安卓网
- SQlException 对象名无效
- 高清录播服务器(服务器是什么)
- composer设置镜像
- word怎么将文档分成三节_分节排版,就是将Word 2010的文档分节,使文档在不同的节中具有不同的______。(2.0分)_学小易找答案...