P1710 地铁涨价

  • 51通过
  • 339提交
  • 题目提供者洛谷OnlineJudge
  • 标签O2优化云端评测2
  • 难度提高+/省选-

提交  讨论  题解

最新讨论

  • 求教:为什么只有40分
  • 数组大小一定要开够啊...
  • 如果强制在线会怎么样
  • 请问为什么第二段铁路变化后…
  • 话说这题和初赛的最后一个大…

题目背景

本题开O2优化,请注意常数

题目描述

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

地铁计价方式很简单。从A站到B站,每经过一小段铁路(连接直接相邻的两个点的一条边),就要收取1博艾元。也就是说,从A站到B站,选择的路径不一样,要价也会不同。

我们认为凡华中学在1号地铁站。学生们通过地铁通勤,他们当然知道选择最短路来坐车的话,票价最便宜。

然而博艾地铁公司经营不善,一直亏损,于是他们打算提价。提价一次就是将一小段铁路原来收费1元改收2元。同一小段的铁路不会多次提价。他们打算提价Q次。

学生们知道,如果他们到学校的一条最短路径中的一小段提价了,可以改变路径,使总票价不变。然而随着一条一条的铁路被提价,当居住在某个站附近的学生发现,提价后,没有任何一种方案可以从家到学校的费用和初始费用相等时,就会不满。

现在地铁公司希望知道,对于每一次涨价,有多少个站,学生会因为涨价而不满呢?

输入输出格式

输入格式:

第一行为三个整数N,M,Q。

接下来M行,每行2个整数ai,bi,表示第i条铁路连接的两个站。i表示铁路编号。

接下来Q行,每行一行整数rj,表示每次涨价的铁路编号。

输出格式:

Q行。每行一个整数表示不满的车站数量。

输入输出样例

输入样例#1

5 6 5

1 2

1 3

4 2

3 2

2 5

5 3

5

2

4

1

3

输出样例#1

0

2

2

4

4

说明

【样例解释】

次数 车站2 车站3 车站4 车站5

初始 1     1     2     2

1    1     1     2     2

2    1     2     2     3

3    1     2     2     3

4    2     2     3     3

5    2     2     4     3

【数据范围】

对于20%的数据 N≤100, Q≤30

对于40%的数据 Q≤30

对于70%的数据 正确的输出结果中,不会有超过50种不一样的整数(数据范围剧透解法系列)

对于100%的数据 N≤100000, Q≤M≤200000

分析:难度比较大的一题,如果先求出最短路,然后删边再求一次最短路能得40分,必须要提高效率.首先,删的边只有在从1到每个点的最短路上才有用,我们可以用bfs求出最短路图,即1到每个点的最短路的图,判断一条边删掉之后有多少个点的最短路会变,那么从1到这个点的最短路数量一定多于1,会发现并不好记录到每个点的最短路数量,那么我们可以把原本的无向图变成一个DAG,即求最短路图的时候只连一条边,我们在求出最短路图的时候顺便记录下每个点的父亲数,这样的话能判断最短路的数量.

然后开始删边,这里不能单单只删两个点,可能两个点都被记录了但不是同一条边,正确的做法是记录边。如果删的这条边是最短路图上的边,那么从这条边指向的点开始dfs,如果这个点的父亲数-1后恰好等于0,那么1到这个点的最短路被改变了,从这个点开始继续dfs,标记被删边影响到的点.

当然,可以考虑离线做法,即将删边变成加边,不过dfs的意义和删边恰好相反,知道可以这么做即可。

不过本题的数据非常诡异,数组的大小要非常小心的确定,不然就会70分.

70分加边代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm> using namespace std; const int maxn = ; int n, m, q,cnt = ,d1[maxn],ans[maxn],qq[maxn],pd[maxn],vis[maxn],flag[maxn],viss[maxn];
int head[maxn], to[maxn], nextt[maxn], tot1 = ;
int head1[maxn], to1[maxn], nextt1[maxn], tot2; struct node
{
int x, y;
}e[maxn]; void add(int x, int y)
{
tot1++;
to[tot1] = y;
nextt[tot1] = head[x];
head[x] = tot1;
} void add2(int x, int y)
{
tot2++;
to1[tot2] = y;
nextt1[tot2] = head1[x];
head1[x] = tot2;
} void bfs1()
{
queue <int> q;
viss[] = ;
q.push();
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = head[u]; i; i = nextt[i])
{
int v = to[i];
if (!viss[v])
{
d1[v] = d1[u] + ;
q.push(v);
viss[v] = ;
}
}
}
} void bfs2()
{
memset(viss, , sizeof(viss));
queue <int> q;
viss[] = ;
q.push();
while (!q.empty())
{
int u = q.front();
q.pop();
for (int i = head[u]; i; i = nextt[i])
{
int v = to[i];
if (d1[v] == d1[u] + )
flag[i / ] = ;
if (!viss[v])
{
viss[v] = ;
q.push(v);
}
}
}
} void dfs(int u)
{
cnt++;
vis[u] = ;
for (int i = head1[u]; i; i = nextt1[i])
{
int v = to1[i];
if (!vis[v])
dfs(v);
}
} int main()
{
scanf("%d%d%d", &n, &m, &q);
for (int i = ; i <= m; i++)
{
int a, b;
scanf("%d%d", &a, &b);
e[i].x = a, e[i].y = b;
add(a, b);
add(b, a);
}
bfs1();
bfs2(); for (int i = ; i <= q; i++)
{
int a;
scanf("%d", &a);
pd[a] = ;
qq[i] = a;
}
for (int i = ; i <= m; i++)
if (d1[e[i].x] > d1[e[i].y])
swap(e[i].x, e[i].y);
vis[] = ,cnt = ;
for (int i = ; i <= m; i++)
if (!pd[i] && flag[i])
{
if (vis[e[i].x] && vis[e[i].y])
continue;
add2(e[i].x, e[i].y);
if (vis[e[i].x])
dfs(e[i].y);
}
ans[q] = n - cnt;
for (int i = q - ; i; i--)
{
int temp = qq[i + ];
//if (e[temp].x && e[temp].y)
//continue;
if (!(vis[e[temp].x] && vis[e[temp].y]) && flag[temp])
add2(e[i].x, e[i].y);
if (vis[e[temp].x] && flag[temp] && !vis[e[temp].y])
dfs(e[temp].y);
ans[i] = n - cnt;
}
for (int i = ; i <= q; i++)
printf("%d\n", ans[i]); //while (1); return ;
}

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std; struct Edge {
int u, v;
} edge[]; int n, m, q, B, ans = ;
vector<int> aG[];
vector<int> G[];
int fa[];
int query[];
queue<int> Q;
int d[];
int r_u[], r_v[];
bool vis[];
bool cnt[]; inline int min(int x, int y) { return x > y ? y : x; }
inline int max(int x, int y) { return x < y ? y : x; } inline void addedge2(int a, int b) {
edge[B].u = a, edge[B].v = b;
aG[a].push_back(B++);
} inline void addedge(int a, int b) {
edge[B].u = a, edge[B].v = b;
fa[b] ++;
G[a].push_back(B++);
} inline void in() {
int i, a, b, c;
scanf("%d%d%d", &n, &m, &q);
for (i = ; i <= m; i++) {
scanf("%d%d", &a, &b);
addedge2(a, b);
addedge2(b, a);
r_u[i] = a, r_v[i] = b;
}
for (i = ; i < q; i++) scanf("%d", query + i);
} inline void BFS() {
int sz, x, i;
memset(d, 0x3f, sizeof(d));
vis[] = , d[] = , Q.push();
while (!Q.empty()) {
x = Q.front(); Q.pop();
sz = aG[x].size();
for (i = ; i < sz; i++) {
Edge& e = edge[aG[x][i]];
if (d[e.v] == d[x] + ) addedge(x, e.v);
if (!vis[e.v]) {
d[e.v] = d[x] + , addedge(x, e.v);
vis[e.v] = ;
Q.push(e.v);
}
}
}
} inline void _del(int x) {
cnt[x] = ;
int i, u = edge[x].u, v = edge[x].v;
fa[v] --;
if (fa[v] >= || fa[v] < ) return;
ans++;
//cout << v <<' '<<fa[v] << endl;
int sz = G[v].size();
for (i = ; i < sz; i++) {
Edge& e = edge[G[v][i]];
if (!cnt[G[v][i]] && d[e.v] == d[v] + ) _del(G[v][i]);
}
} //建最短路DAG,然后删边时看看儿子的所有父亲能不能连过来,能的话就不变,不能的话说明儿子不是最短路了,需要切除其所有出边,重复刚刚的过程 inline void solve() {
int i, j;
BFS();
for (i = ; i <= m; i++) {
if (d[r_u[i]] > d[r_v[i]]) swap(r_u[i], r_v[i]);
}
for (i = ; i < q; i++) {
int sz = G[r_u[query[i]]].size();
for (j = ; j < sz; j++) {
Edge& e = edge[G[r_u[query[i]]][j]];
if (e.v == r_v[query[i]]) {
if (!cnt[G[r_u[query[i]]][j]])
_del(G[r_u[query[i]]][j]);
break;
}
}
printf("%d\n", ans);
}
} int main() {
in();
solve();
return ;
}

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

  1. 洛谷 P1710 地铁涨价

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

  2. 洛谷P1710地铁涨价

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

  3. 洛谷P1710 地铁涨价 图论

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

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

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

  5. uva A Spy in the Metro(洛谷 P2583 地铁间谍)

    A Spy in the Metro Secret agent Maria was sent to Algorithms City to carry out an especially dangero ...

  6. P1710 地铁涨价

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

  7. 洛谷P2583 地铁间谍

    P2583 地铁间谍 题目描述 特工玛利亚被送到S市执行一个特别危险的任务.她需要利用地铁完成他的任务,S市的地铁只有一条线路运行,所以并不复杂. 玛利亚有一个任务,现在的时间为0,她要从第一个站出发 ...

  8. luogu P1710 地铁涨价

    嘟嘟嘟 一道最短路好题. 首先明确一点,把一条边的边权变成2,等于删去这条边.因为变成2后最短路肯定不会经过这条边,就相当于删去这条边了. 所以题目变成了依次删去Q条边,求每一次删完边后有几个点的最短 ...

  9. 洛谷10月月赛Round.3

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

随机推荐

  1. 备忘DES简单加密与解密

    package com.ego.util; import java.io.IOException; import java.security.SecureRandom; import javax.cr ...

  2. PS中的图像知识

    图像处理对于前端工作来说是一个不能回避的问题,ps技术也是我们必备的技能.用法可以在使用中不断的熟练,但针对前端技术本身的一些知识点,需要我们平时不断的积累才能够在使用中不出现问题. 如今的办公,已经 ...

  3. 【python】jiraAPI使用教程 自动创建jira问题单并置状态为OPEN

    环境依赖 : python库 redis jira  安装命令:pip install redis pip install jira redis服务安装命令: $sudo apt-get update ...

  4. Linux上搭建Elasticsearch服务器并同步数据库

    1.准备工作         下载Elasticsearch版本号2.3.4 https://www.elastic.co/downloads/past-releases/elasticsearch- ...

  5. [Thinking in Java]Nothing but Java

    1 对象(Double Elephants) 1.1 抽象 万物皆对象.什么东西都可以抽象成属性和方法,达到可重用的目的. 对象之间交流靠发送消息.就是通过调用某个特定对象的方法来达到消息传递的目的. ...

  6. FreeBSD 无线配置

    无线配置在 handbook 中早已有了,但 handbook 中采用写入配置文件的办法,缺乏灵活性,补充下 on the fly 的方法 假设网卡接口为 ath0 ifconfig wlan0 cr ...

  7. 注册noip.com动态域名的步骤

    1.先打开这个网址 http://www.noip.com/ 2.点击页面右上绿色的Sing Up,进行注册 3.会出现这个页面,把这些填上 Create my hostname later这一项不打 ...

  8. spring加载bean实例化顺序

    问题来源: 有一个bean为 A,一个bean为B.想要A在容器实例化的时候的一个属性name赋值为B的一个方法funB的返回值. 如果只是在A里单纯的写着: private B b;private ...

  9. LeetCode "473. Matchsticks to Square"

    A trickier DFS, with a little bit complex recursion param tweak, and what's more important is prunin ...

  10. mybatis实战教程(mybatis in action)之四:实现关联数据的查询

    有了前面几章的基础,对一些简单的应用是可以处理的,但在实际项目中,经常是关联表的查询,比如最常见到的多对一,一对多等.这些查询是如何处理的呢,这一讲就讲这个问题.我们首先创建一个Article 这个表 ...