嘟嘟嘟

一道最短路好题。

首先明确一点,把一条边的边权变成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数组就够,标记过就表示这个点已经成为了最短路,不用记录他的距离。

  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 地铁涨价相关推荐

  1. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

  2. 洛谷 P1710 地铁涨价 (dfs+bfs)

    地铁涨价 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地铁连接两个不同的站. 地铁计 ...

  3. 洛谷 P1710 地铁涨价

    题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...

  4. 洛谷P1710地铁涨价

    题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...

  5. P1710 地铁涨价

    题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...

  6. 题目 - 北京地铁 描述 北京地铁涨价了,现在的地铁票价计算方法如下: 6公里内 3元 (包括6公里) 6-12 公里 4元 (不包括6公里,包括12公里) 12-32 公里 每10公里加1元

    题目 - 北京地铁 描述 北京地铁涨价了,现在的地铁票价计算方法如下: 6公里内 3元 (包括6公里) 6-12 公里 4元 (不包括6公里,包括12公里) 12-32 公里 每10公里加1元(不包括 ...

  7. 【洛谷 P1710】地铁涨价(dfs+bfs)

    [题解][BFS+dfs] [图论题] [通过分析题目,我们可得知改变边权实际就是在删边.那么,如果每次删一条边,那么就要重新跑最短路,这样必然会T] [考虑离线处理,改删边位加边,看每次加一条边,有 ...

  8. 洛谷1710 地铁涨价

    题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...

  9. [luogu1710]地铁涨价(bfs)

    题目描述 传送门 题解 转化问题 这里路线涨价明显等同于删边,所以我们可以把问题倒过来思考: 图上依次(倒序)加边,问每个点成为最终图最短路的时间 分析 记原图的点1到达点i的最短路为dis[i],当 ...

最新文章

  1. 对order by的理解
  2. tensorflow1.14.0  包含了1.x和2.x内容,此后版本要求兼容该版本
  3. 20162311 算法复杂度-3
  4. 易宝典——玩转O365中的EXO服务 之四十 创建就地电子数据展示搜索
  5. Cambridge partner
  6. 天平游码读数例题_初二上册物理实验——托盘天平使用的注意事项
  7. Java并发编程(01):线程的创建方式,状态周期管理
  8. docker容器内漏洞_如何在2020年发现和修复Docker容器漏洞
  9. 存储过程,游标和触发器实例
  10. c语言warning scanf,【C】将m~n之间的素数输出与VS2005以上版本对C语言的scanf的警告warning C4996...
  11. 提高工作沟通技巧,加强沟通,不要推测他人发生问题发生的原因
  12. bzoj 2560: 串珠子【状压dp】
  13. 吟诗作赋不能赚钱,作诗的AI机器人的盈利之路在哪
  14. 宝塔面板FTP存储空间无法连接的问题
  15. 游戏开发工程师岗位要求
  16. 保护眼睛android版本,夜间护眼软件下载-夜间护眼 安卓版v4.9.1-PC6安卓网
  17. SQlException 对象名无效
  18. 高清录播服务器(服务器是什么)
  19. composer设置镜像
  20. word怎么将文档分成三节_分节排版,就是将Word 2010的文档分节,使文档在不同的节中具有不同的______。(2.0分)_学小易找答案...

热门文章

  1. 【SDOI2009】学校食堂
  2. 家里WiFi慢?几招帮你解决
  3. u盘格式化后数据能恢复吗?
  4. LeetCode数据库题目1-123
  5. C++ 宽、窄字符转换
  6. 2019 年 DevOps 实践中最有价值的技能
  7. 小队pkc++_骑士小队2人金属第一印象
  8. linux下格式化U盘的方法
  9. phpstorm快速编辑模板技巧
  10. 利用虚拟机实时迁移技术可以实现服务器的,VMware vMotion虚拟机的实时迁移技术概述...