zoukankan      html  css  js  c++  java
  • 【POJ3255/洛谷2865】[Usaco2006 Nov]路障Roadblocks(次短路)

    题目:

    POJ3255

    洛谷2865

    分析:

    这道题第一眼看上去有点懵……

    不过既然要求次短路,那估计跟最短路有点关系,所以就拿着优先队列优化的Dijkstra乱搞,搞着搞着就通了。

    开两个数组:(dis)存最短路,(dis2)存次短路

    在松弛的时候同时更新两个数组,要判断三个条件

    (u)是当前考虑的点,(v)是与(u)有边相连的点,(d(u,v))表示从(u)(v)的边长)

    1.如果(dis[v]>dis[u]+d(u,v)),则更新(dis[v])

    2018.11.09Updated: 同时(dis2[v])应成为原(dis[v])。原代码有误,已更新。

    2.如果(dis[v]<dis[u]+d(u,v))(不能取等,否则(dis2[v])(dis[v])可能相等)且(dis2[v]>dis[u]+d(u,v)),则更新(dis2[v])

    3.如果(dis2[v]>dis2[u]+d(u,v)),则更新(dis2[v])(显然,如果2成立,更新后(dis2[v]=dis[u]+d(u,v)<dis2[u]+d(u,v)),即3一定不成立)

    如果上述三个条件中有任意一个成立,则将(v)入队。

    还要注意一个地方:因为次短路可能会走“回头路” (即成环) ,所以一个点可以多次进队,不能使用(vis)数组判重。

    以及起点的(dis2)不能初始化为0,因为起点的次短路一定是沿着与其相连的最短的边走出去再回来。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<queue> 
    #include<cstring>
    #include<vector>
    using namespace std;
    int dis[5010],dis2[5010],n,m;
    struct point
    {
    	int id;
    	int dis;
    	bool operator<(const point &b)const
    	{
    		return dis>b.dis;
    	}
    };
    struct edge
    {
    	int to;
    	int w;
    };
    priority_queue<point>q;
    vector<edge>g[5010];
    int main(void)
    {
    	scanf("%d%d",&n,&m);
    	for(int i=0;i<m;i++)
    	{
    		int a,b,c;
    		scanf("%d%d%d",&a,&b,&c);
    		g[a].push_back((edge){b,c});
    		g[b].push_back((edge){a,c});
    	}
    	memset(dis,0x3f3f3f3f,sizeof(dis));
    	memset(dis2,0x3f3f3f3f,sizeof(dis2));
    	dis[1]=0;
    	q.push((point){1,0});
    	while(!q.empty())
    	{
    		int u=q.top().id,d=q.top().dis;
    		q.pop();
    		if(d>dis2[u])continue;
    		for(int i=0;i<g[u].size();i++)
    		{
    			int v=g[u][i].to,w=g[u][i].w;
    			bool flag=false;
    			if(dis[v]>dis[u]+w)
    			{
    				dis2[v]=dis[v];
    				dis[v]=dis[u]+w;flag=true;
    			}
    			if(dis[v]<dis[u]+w&&dis2[v]>dis[u]+w)
    				dis2[v]=dis[u]+w,flag=true;
    			
    			if(dis2[v]>dis2[u]+w)
    				dis2[v]=dis2[u]+w,flag=true;
    				
    			if(flag)q.push((point){v,dis[v]});
    		}
    	}
    	printf("%d",dis2[n]);
    	return 0;
    }
    
  • 相关阅读:
    POJ 3320 Jessica's Reading Problem
    引用参数和传值参数的区别
    IBM 的数据库Informix 常用代语法
    设计模式之原型模式
    UBoot中使用tftp下载文件出现错误TFTP error: 'Access violation' (2)的解决办法
    printf格式控制符的完整格式
    如何打印hostent结构体中的所有数据
    Informix 数据库客户端 dbvisualizer SQL Commander 乱码解决方案
    设计模式之模版方法模试
    nfs: server 192.168.37.200 not responding, still trying的解决办法
  • 原文地址:https://www.cnblogs.com/zyt1253679098/p/8867678.html
Copyright © 2011-2022 走看看