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. Oracle启动脚本,开机自启动设置

    #!/bin/sh # chkconfig: # description: Oracle auto start-stop script. # # Set ORA_HOME to be equivale ...

  2. Unicode 和 UTF-8 的关系

    曾经这个世界上,有着gb2312,gbk,latin1,utf 等各种字符集,现在,我们也能不时的看到他们的身影. 但是值得庆幸的事,时过境迁,这些主要的字符集,都已经逐渐被utf8取代. 但是我们很 ...

  3. python-语句

    assert语句 用来声明某个条件是真的.例如,如果你非常确信某个你使用的列表中至少有一个元素,而你想要检验这一点,并且在它非真的时候引发一个错误,那么assert语句是应用在这种情形下的理想语句.当 ...

  4. jdk环境变量配置

    新建用户变量PATH,编辑jdk路径. 仅此而已.

  5. C++ 资源大全

    http://www.uml.org.cn/c++/201411145.asp http://ezlippi.com/blog/2014/12/c-open-project.html <C++ ...

  6. LB(Load balance)负载均衡集群--{LVS-[NAT+DR]单实例实验+LVS+keeplived实验} 菜鸟入门级

    LB(Load balance)负载均衡集群 LVS-[NAT+DR]单实例实验 LVS+keeplived实验 LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一 ...

  7. 大数据量下,分页的解决办法,bubuko.com分享,快乐人生

    大数据量,比如10万以上的数据,数据库在5G以上,单表5G以上等.大数据分页时需要考虑的问题更多. 比如信息表,单表数据100W以上. 分页如果在1秒以上,在页面上的体验将是很糟糕的. 优化思路: 1 ...

  8. Apache Shiro 简单概念

    Apache Shiro 是ASF旗下的一款开源软件(Shiro发音为"shee-roh",日语"堡垒(Castle)"的意思),提供了一个强大而灵活的安全框架 ...

  9. Mysql大范围分页优化案例

    在BBS线上业务抓到如下分页SQL: meizu_bbs meizu_bbs Query Sending data , meizu_bbs meizu_bbs Query Sending data , ...

  10. 开始使用DOJO(翻译)

    http://dojotoolkit.org/documentation/tutorials/1.10/start/index.html 我怎么开始学习DOJO?文档在哪?我如何获取支持和培训?我应该 ...