嘟嘟嘟

一道最短路好题。

首先明确一点,把一条边的边权变成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. hcheck 脚本

    hcheck.sql - Script to Check for Known Problems in Oracle8i, Oracle9i, Oracle10g, Oracle 11g and Ora ...

  2. 转 How To Stop A Running Job Using DBMS_JOB

    There is no procedure within the dbms_job package to stop a running job.You will need to determine w ...

  3. oracle OEM安装(一)

    01,用户解锁添加密码 [oracle@oracle01 ~]$ sqlplus / as sysdba SQL Production :: Copyright (c) , , Oracle. All ...

  4. mysql DML语句

    1, 插入数据 insert into emp1(ename,hiredate,sal,deptono) values('kingle','2000-01-01','2000',1); 插入数据加入需 ...

  5. Permanent data region free space insufficient to allocate 64792 bytes of memory

    TT0802: Database permanent space exhaustedTT6220: Permanent data region free space insufficient to a ...

  6. java连接redis使用jedis带密码

    一.引入jedis的Maven配置文件 <!-- redis连接客户端jedis --> <dependency> <groupId>redis.clients&l ...

  7. cmd激活win10

    自己动手,KMS激活win10 2016 长期服务版.步骤如下:命令提示符(管理员),依次输入以下3条命令 slmgr /ipk DCPHK-NFMTC-H88MJ-PFHPY-QJ4BJslmgr ...

  8. unity监听键盘按键

    放在Update里面 if (Input.anyKeyDown) { foreach (KeyCode keyCode in Enum.GetValues(typeof(KeyCode))) { if ...

  9. FZU 2122——又见LKity——————【字符串匹配、暴力】

    Problem 2122 又见LKity Accept: 407    Submit: 1413Time Limit: 1000 mSec    Memory Limit : 32768 KB  Pr ...

  10. nyoj 206——矩形的个数——————【dp或公式】

    矩形的个数 时间限制:1000 ms  |  内存限制:65535 KB 难度:1   描述 在一个3*2的矩形中,可以找到6个1*1的矩形,4个2*1的矩形3个1*2的矩形,2个2*2的矩形,2个3 ...