洛谷P1710地铁涨价
题目背景
本题开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[/code]
【数据范围】
对于20%的数据 N≤100, Q≤30
对于40%的数据 Q≤30
对于70%的数据 正确的输出结果中,不会有超过50种不一样的整数(数据范围剧透解法系列)
对于100%的数据 N≤100000, Q≤M≤200000
所有边权都是1,那么如果一条边原来在最短路上,边权增加以后,它就不再在原图的最短路上了。
于是问题转化成:求从最短路图中删边带来的影响
大概90%的删边问题都可以转化成:在一个所有需要删的边都删掉的图中,倒序加边
先求出原图最短路,然后把将要删的边都删掉。倒序加边,每次加边计算有多少个点到1的最短距离和原图上该点到1的最短距离相等。
之后答案求前缀和即可。
刚开始谜之30分,怒看题解。
当我发现我得代码和题解神似的时候,我的内心是欣喜的。
当我发现我WA是因为变量用混的时候,我的内心是崩溃的。
/*By SilverN*/ #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define LL long long using namespace std; const int mxn=200010; int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,q; struct mapp{ int x,y; }eg[mxn]; struct edge{ int v,nxt,id; }e[mxn<<1]; int hd[mxn],mct=0; void add_edge(int u,int v,int id){ e[++mct].v=v;e[mct].nxt=hd[u];e[mct].id=id;hd[u]=mct; } // int qe[mxn];bool ban[mxn]; int dis[mxn],mdis[mxn]; int ans[mxn]; int que[mxn];bool vis[mxn]; void BFS(){ int hed=0,tl=1,i,j; que[++hed]=1;vis[1]=1; dis[1]=1; while(hed<=tl){ int u=que[hed++]; for(i=hd[u];i;i=e[i].nxt){ int v=e[i].v; if(vis[v])continue; dis[v]=dis[u]+1; vis[v]=1; que[++tl]=v; } } return; } int DFS(int u,int fa){ int res=0; for(int i=hd[u],v;i;i=e[i].nxt){ v=e[i].v; if(v==fa)continue; if(dis[v]!=dis[u]+1 && mdis[v]==dis[u]+1){ dis[v]=dis[u]+1; res++; res+=DFS(v,u); } } return res; } void sol(){ int i,j; for(i=q;i;--i){ int now=qe[i]; int x=eg[now].x,y=eg[now].y; add_edge(x,y,now); add_edge(y,x,now); if(dis[x]==mdis[x]&&dis[y]!=mdis[y]&&mdis[y]==dis[x]+1){ dis[y]=dis[x]+1; ans[i]=DFS(y,x)+1; continue; } if(dis[y]==mdis[y]&&dis[x]!=mdis[x]&&mdis[x]==dis[y]+1){ dis[x]=dis[y]+1; ans[i]=DFS(x,y)+1; } } return; } int main(){ n=read();m=read();q=read(); int i,j,u,v; for(i=1;i<=m;++i){ eg[i].x=read();eg[i].y=read(); add_edge(eg[i].x,eg[i].y,i); add_edge(eg[i].y,eg[i].x,i); } for(i=1;i<=q;++i)qe[i]=read(),ban[qe[i]]=1; BFS(); // memcpy(mdis,dis,sizeof dis);//保存最短距离 memset(dis,0x3f,sizeof dis); memset(vis,0,sizeof vis); memset(e,0,sizeof e); memset(hd,0,sizeof hd); mct=0; //reload for(i=1;i<=m;++i){ if(!ban[i]){ add_edge(eg[i].x,eg[i].y,i); add_edge(eg[i].y,eg[i].x,i); } } dis[1]=1; BFS(); sol(); for(i=1;i<=q;++i){ ans[i]+=ans[i-1]; printf("%d\n",ans[i]); } return 0; }
- 洛谷 P1710 地铁涨价 (dfs+bfs)
- 【洛谷 P1710】地铁涨价(dfs+bfs)
- 洛谷 P1710 地铁涨价
- 洛谷P1710 地铁涨价
- 洛谷 P1710 地铁涨价
- 洛谷1710 地铁涨价
- 地铁涨价,新出台的javase计算每月乘坐地铁消费金额
- 转:北京地铁听证会结束,地铁公交调价方案2胜出,来看看涨价后多了多少钱??
- 洛谷P2583 地铁间谍
- [luogu1710]地铁涨价(bfs)
- luogu P1710 地铁涨价
- 地铁涨价啦~~~
- 转载一篇文章 写的很好 关于北京地铁涨价的
- 洛谷Luogu-2583 地铁间谍 (DP) HQG_AC的博客
- 洛谷2583 地铁间谍 (UVa1025A Spy in the Metro)
- 地铁间谍(洛谷 2583)
- 洛谷 P1196 NOI2002 银河英雄传说
- 洛谷 P1186 玛丽卡
- 地铁译:Spark for python developers ---Spark与数据的机器学习
- 洛谷 排列LCS P1439 (LCS)