嘟嘟嘟

一道最短路好题。

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

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 1e5 + ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = ans * + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n, m, q;
struct Edge
{
int nxt, to;
}e[maxn << ];
int head[maxn], ecnt;
void add(int x, int y)
{
e[++ecnt] = (Edge){head[x], y};
head[x] = ecnt;
} struct Node
{
int x, y;
}egs[maxn << ]; #define pr pair<int, int>
#define mp make_pair
bool in[maxn];
int dis[maxn];
void dijkstra(int s)
{
Mem(dis, 0x3f);
dis[s] = ;
priority_queue<pr, vector<pr>, greater<pr> > q;
q.push(mp(dis[s], s));
while(!q.empty())
{
int now = q.top().second; q.pop();
if(in[now]) continue;
in[now] = ;
for(int i = head[now]; i != -; i = e[i].nxt)
{
if(dis[e[i].to] > dis[now] + )
{
dis[e[i].to] = dis[now] + ;
q.push(mp(dis[e[i].to], e[i].to));
}
}
}
} bool vis[maxn << ];
int a[maxn << ], ans[maxn << ], num; void solve(int now, int d)
{
for(int i = head[now]; i != -; i = e[i].nxt)
{
if(!vis[e[i].to] && d + == dis[e[i].to])
{
num--;
vis[e[i].to] = ;
solve(e[i].to, d + );
}
}
} int main()
{
Mem(head, -); ecnt = -;
n = read(); m = read(); q = read();
for(rg int i = ; i <= m; ++i)
{
egs[i].x = read(); egs[i].y = read();
add(egs[i].x, egs[i].y); add(egs[i].y, egs[i].x);
}
dijkstra();
for(rg int i = ; i <= q; ++i) a[i] = read(), vis[a[i]] = ;
Mem(head, -); ecnt = -;
num = n - ;
for(int i = ; i <= m; ++i) if(!vis[i])
{
int x = egs[i].x, y = egs[i].y;
add(x, y); add(y, x);
}
Mem(vis, ); vis[] = ;
solve(, );
for(rg int i = q; i; --i)
{
ans[i] = num;
int x = egs[a[i]].x, y = egs[a[i]].y;
add(x, y); add(y, x);
if(vis[x]) solve(x, dis[x]);
if(vis[y]) solve(y, dis[y]);
}
for(rg int i = ; i <= q; ++i) write(ans[i]), enter;
return ;
}

luogu P1710 地铁涨价的更多相关文章

  1. 洛谷P1710 地铁涨价

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

  2. P1710 地铁涨价

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

  3. 洛谷 P1710 地铁涨价

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

  4. 洛谷P1710地铁涨价

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

  5. 洛谷P1710 地铁涨价 图论

    其实是个傻逼题但是我太傻逼了然后就错了无数遍总算A了 觉得不写个题解真是亏了 其实是 之前想了个超时想法 然后还自以为很对?后来看了题解发现还是比较妙的哦 于是就想着那还是发个题解记录下趴quq 正解 ...

  6. 洛谷10月月赛Round.3

    Rank11:260=60+100+100 P2409 Y的积木 题目背景 Y是个大建筑师,他总能用最简单的积木拼出最有创意的造型. 题目描述 Y手上有n盒积木,每个积木有个重量.现在他想从每盒积木中 ...

  7. 【luogu P4005 清华集训2017】小Y和地铁

    题目描述 小 Y 是一个爱好旅行的 OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的一条曲线,不同线路的交点处一定会设有 换乘站 . ...

  8. 洛谷2583 地铁间谍 (UVa1025A Spy in the Metro)

    洛谷2583 地铁间谍(UVa1025A Spy in the Metro) 本题地址:http://www.luogu.org/problem/show?pid=2583 题目描述 特工玛利亚被送到 ...

  9. 【清华集训】小Y和地铁

    图已挂,前往luogu 题目: 小 $\rm Y$ 是一个爱好旅行的 $\rm OIer$.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁.她发现每条地铁线路可以看成平面上的一条 ...

随机推荐

  1. Python学习 day08

    一.open打开文件 文件操作包含以下三个步骤: 1.文件路径 2.编码方式 3.操作方式:‘’只读‘’.“只写”.“读写” 等 1.只读 r (mode默认值) 例: f = open('d:\py ...

  2. libevent 同性恋 讲解

    https://aceld.gitbooks.io/libevent/content/25hong_fa_mo_5f0f_md.html github 这url 干活比较好 https://githu ...

  3. Mina入门demo

    初识Mina,简要记录理解内容和实现demo. 这里先简述一下BIO和NIO的区别: 同步阻塞IO(BIO):一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任 ...

  4. 使用SVN进行源码管理

    阅读目录: 1.SVN服务端配置 1.1 创建版本库 1.2 创建用户 1.3 设置用户权限 2.SVN客户端使用 2.1 向SVN服务器中导入源码 2.1.1 直接通过TortoiseSVN向SVN ...

  5. (Frontend Newbie)Web三要素(三)

    上一篇简单介绍了Web三要素中的层叠样式表,本篇主要介绍三要素中最后一个,也是最难掌握的一个-----JavaScript. JavaScript 老规矩不能破,先简要交代 JavaScript 的历 ...

  6. unity向量计算

    参考:https://www.cnblogs.com/wywnet/p/4790665.html 上面的文章讲的很重要 下面是我自己实现的一个例子 一直一个向量,一个夹角,求另一个向量 按P键改变夹角 ...

  7. 使用params

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. js判断触摸方向

    $("body").on("touchstart", function(e) { e.preventDefault(); startX = e.original ...

  9. 程序包com.sun.image.codec.jpeg不存在

    在pox.xml中引入依赖 <dependency><groupId>rt</groupId><artifactId>rt</artifactId ...

  10. 【卷土重来之C#学习笔记】(三) 类的基本概念

    1.类的概述   程序的数据和功能被组织为逻辑上相关的数据项和函数的封装集合,并被称为类.   类是一个能存储数据并执行代码的数据结构. 它包含数据成员和函数成员: 数据成员:存储与类或类的实例相关数 ...