Codeforces Round #257 div.2 D or 450D Jzzhu and Cities【最短路】
来源:互联网 发布:js push unshift 编辑:程序博客网 时间:2024/05/22 05:12
Codeforces Round #257 div.2 D or 450D Jzzhu and Cities【最短路】
题目链接:点击打开
题目大意:
在一个国家中有n个城市(城市编号1~n),m条公路和k条铁路,编号为1的城市为首都,为了节约,不需要的铁路需要关闭,问在保证首都到其余所有城市的最短路不变的条件下,最多有多少条铁路是不需要的。解法:
这个题比较麻烦,保证首都到其余城市的最短路不变,要求出最多有多少条铁路是不需要的,那肯定是从最短路的代码上下手了,我们首先考虑dijkstra算法,假设此时我们处理的图没有重边。- 由于要使不需要的铁路最多,那么我们的用来做最短路的路径上的边应该尽可能保证是公路,也就是说,当从首都到某个城市的最短路有多条的时候,我们应该选择铁路最少的一条。那么我们在算法中的“松弛”操作中应该加上这个判断。
- 我们可以利用一个path[]数组记录哪两个点之间的边是最短路径上的边,记录下这个,我们就可以在遍历过程中方便的判断哪些铁路是不需要的,哪些铁路是在最短路径上的,以此来得到答案。其中path[v]=u,表示(u,v)这条边在最短路径上。由于没有重边,所以这样是能够确定一条边的。
- 由于前面的结论是在图中没有重边的基础上得出的,然而题目却会给出有重边的数据,于是我们应该先去掉原有数据中的重边。去除重边的时候,要留下两个城市之间边权值最小的一条,这一条尽可能是公路,去除重边的同时,被去除掉的铁路也应该记入答案中。
让我百思不得其解的是,我写完此题submit之后居然给我返回了一个MLE!让我想半天想不通,CF服务器内存限制一直是256MB,很少出现这种情况,也不可能是数组太大的缘故,我想了很久,突然想到很有可能是dijkstra算法中的优先队列存的数据太多导致的内存超出限制,于是赶紧加了一条限制。果然就过了。
//MLE code(松弛部分):
if(d[v]>d[u]+w || (d[v]==d[u]+w && !is))
{
path[v]=u;
d[v]=d[u]+w;
que.push(PII(d[v],v));
}
//AC code(松弛部分):
if(d[v]>d[u]+w || (d[v]==d[u]+w && !is && trainofpath[v]))
{
trainofpath[v]=is;
path[v]=u;
d[v]=d[u]+w;
que.push(PII(d[v],v));
}
这里采用了一个布尔数组trainofpath[v]记录到v点的这条边是不是铁路。如果这条路原本是铁路,现在更新的是公路,才进行更新;想上一份MLE的代码如果只要当前更新的是公路就进行操作的话,一些变态的数据会使得压入优先队列中的数据过多,导致MLE。
完整代码如下:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#define N 200010using namespace std;const long long INF=0x7fffffffffffffffL;struct edge{ long long u,v,w,nxt; bool istrain; bool operator< (const edge& o) const { return u<o.u||(u==o.u && v<o.v) ||(u==o.u && v==o.v && w<o.w) ||(u==o.u && v==o.v && w==o.w && istrain<o.istrain); }}e1[N*4],e[N*3];long long last[N];typedef pair<long long,long long> PII;long long V;long long d[N];long long path[N];bool trainofpath[N];priority_queue<PII,vector<PII>,greater<PII> > que;void dijkstra(long long s){ //memset(d,0x3f,sizeof(d)); fill(d+1,d+V+1,INF); d[s]=0; que.push(PII(0,s)); while(!que.empty()) { PII pp=que.top();que.pop(); long long u=pp.second; if(d[u]<pp.first) continue; for(long long i=last[u];i!=-1;i=e[i].nxt){ long long v=e[i].v,w=e[i].w; bool is=e[i].istrain; if(d[v]>d[u]+w || (d[v]==d[u]+w && !is && trainofpath[v])) { trainofpath[v]=is; path[v]=u; d[v]=d[u]+w; que.push(PII(d[v],v)); } } }}int main(){ long long n,m,k; scanf("%I64d%I64d%I64d",&n,&m,&k); V=n; long long ans=0; memset(last,-1,sizeof(last)); for(int i=0;i<=n;i++) { trainofpath[i]=true; } for(long long i=0;i<m;i++) { long long u,v,w; scanf("%I64d%I64d%I64d",&u,&v,&w); if(u>v) swap(u,v); e1[i].u=u,e1[i].v=v,e1[i].w=w,e1[i].istrain=false; } for(long long i=0;i<k;i++) { long long v,w; scanf("%I64d%I64d",&v,&w); e1[i+m].u=1,e1[i+m].v=v,e1[i+m].w=w,e1[i+m].istrain=true; } sort(e1,e1+m+k); long long edge1Num=1; for(long long i=1;i<m+k;i++) { if(e1[i].u==e1[i-1].u && e1[i].v==e1[i-1].v) { if(e1[i].istrain) ans++; continue; } e1[edge1Num++]=e1[i]; } long long edgeNum=0; for(long long i=0;i<edge1Num;i++) { long long u=e1[i].u,v=e1[i].v,w=e1[i].w; bool is=e1[i].istrain; e[edgeNum].u=u,e[edgeNum].v=v,e[edgeNum].w=w,e[edgeNum].istrain=is,e[edgeNum].nxt=last[u],last[u]=edgeNum++; e[edgeNum].v=u,e[edgeNum].u=v,e[edgeNum].w=w,e[edgeNum].istrain=is,e[edgeNum].nxt=last[v],last[v]=edgeNum++; } dijkstra(1); for(long long i=0;i<edgeNum;i+=2) { long long u=e[i].u,v=e[i].v; bool is=e[i].istrain; if(!is) continue; if(path[v]==u || path[u]==v) continue; ans++; } cout<<ans<<endl; return 0;}
(这次试了一下新功能Markdown编辑器^_^不怎么会用,看起来比较丑,不过代码显示好像没有以前的漂亮…..可能还需要学习一下新的姿势,嘿嘿)
0 0
- Codeforces Round #257 div.2 D or 450D Jzzhu and Cities【最短路】
- Codeforces Round #257 (Div. 2) D Jzzhu and Cities 最短路
- Codeforces Round #257 (Div. 2) D题:Jzzhu and Cities 删特殊边的最短路
- Codeforces Round #257 (Div. 2) D. Jzzhu and Cities
- Codeforces Round #257 (Div. 1) B. Jzzhu and Cities (记录最短路数量)
- CODEFORCES 450D Jzzhu and Cities <最短路径>
- Codeforces Round #257 (Div. 1) D. Jzzhu and Numbers
- 文章标题 CoderForces 450D : Jzzhu and Cities(最短路---spfa)
- Codeforces 449B - Jzzhu and Cities / 450D - Jzzhu and Cities
- D. Jzzhu and Cities
- CodeForces 450D - Jzzhu and Cities (dij + heap )
- Codeforces Round #302 (Div. 2) D. Destroying Roads(最短路)
- Codeforces Round #302 (Div. 2)D. Destroying Roads-最短路
- Codeforces Round #302 (Div. 2) D bfs最短路
- 08/13 D -> codeforces Round #Pi div 2 E. President and Roads 最短路变形
- Codeforces Round #420 (Div. 2) D. Okabe and City (最短路)
- Codeforces Round #420 (Div. 2) D. Okabe and City(最短路)
- Codeforces Round #420 (Div. 2) D. Okabe and City 最短路
- 排除SCO UNIX系统故障实例
- H3C SecPath 防火墙设置之端口映射(命令)
- 蓝的成长记——追逐DBA(14): 难忘的“云”端,起步的hadoop部署
- LIUNX ARM 启动流程分析
- c#网络编程常用特性之方法回调
- Codeforces Round #257 div.2 D or 450D Jzzhu and Cities【最短路】
- com.microsoft.sqlserver.jdbc.SQLServerException: 对象名 'xxxxx' 无效
- 函数指针解析(C语言)
- scanf函数缓冲区问题探究
- shell基础和简单入门
- linux系统文件类型总结
- 在开发android时不能生成 r.java 文件
- 常用标准I/O库函数总结
- 链接