zoukankan      html  css  js  c++  java
  • 洛谷 P2865 [USACO06NOV]路障Roadblocks

    题目

    题意:求无向图中起点到终点的次短路。

    思路:用两次dijkstra,分别正向和反向遍历一边,求出到起点的最短路dis1[]和到终点的最短路dis2[],然后再枚举每一条边 $ u->v $ ,令
    $ d = dis1[u] + dis2[y] + edge.w $ ,在满足 $ d<dis1[n] $ 的条件下求出最小的d即为次短路的长度。

    Code:

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    //Mystery_Sky
    //
    #define M 1000100
    struct Edge{
    	int to, w, next;
    }edge[M];
    int n, m;
    int head[M], cnt, dis1[M], dis2[M], vis[M];
    inline void add_edge(int u, int v, int w) {edge[++cnt].to = v; edge[cnt].w = w; edge[cnt].next = head[u]; head[u] = cnt;}
    struct node{
    	int dis;
    	int pos;
    	inline bool operator <(const node &x)const{
    		return x.dis < dis;
    	}
    };
    priority_queue <node> Q;
    inline void dijkstra()
    {
    	dis1[1] = 0;
    	Q.push((node){0, 1});
    	while(!Q.empty()) {
    		node top = Q.top(); Q.pop();
    		int x = top.pos;
    		if(vis[x]) continue;
    		vis[x] = 1;
    		for(int i = head[x]; i; i = edge[i].next) {
    			int y = edge[i].to;
    			if(dis1[y] > dis1[x] + edge[i].w) {
    				dis1[y] = dis1[x] + edge[i].w;
    				if(!vis[y]) Q.push((node){dis1[y], y}); 
    			}
    		}
    	} 
    }
    
    inline void dijkstra_1()
    {
    	memset(vis, 0, sizeof(vis));
    	dis2[n] = 0;
    	Q.push((node){0, n});
    	while(!Q.empty()) {
    		node top = Q.top(); Q.pop();
    		int x = top.pos;
    		if(vis[x]) continue;
    		vis[x] = 1;
    		for(int i = head[x]; i; i = edge[i].next) {
    			int y = edge[i].to;
    			if(dis2[y] > dis2[x] + edge[i].w) {
    				dis2[y] = dis2[x] + edge[i].w;
    				if(!vis[y]) Q.push((node){dis2[y], y}); 
    			}
    		}
    	} 
    }
    int main() {
    	scanf("%d %d", &n, &m);
    	for(int i = 1; i <= m; i++) {
    		int u, v, w;
    		scanf("%d %d %d", &u, &v, &w);
    		add_edge(u, v, w); add_edge(v, u, w);
    	}
    	for(int i = 1; i <= n; i++) dis1[i] = dis2[i] = 0x3f3f3f3f;
    	dijkstra();
    	dijkstra_1();
    	int ans = 0x3f3f3f3f;
    	for(int i = 1; i <= n; i++) {
    		for(int j = head[i]; j; j = edge[j].next) {
    			int y = edge[j].to;
    			int d = dis1[i] + dis2[y] + edge[j].w;
    			if(d < ans && d > dis1[n]) ans = d;
    		}
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    django 从零开始 9 自定义密码验证加密
    OJ建站之Virtual Judge系统搭建
    OJ建站之HUSTOJ搭建
    Android Studio:Gradle DSL method not found: 'runProguard()'
    品牌笔记本预装windows的OEM分区解决方案(联想)
    Win8/8.1 下映像管理和恢复环境的配置
    POJ 2728 Desert King 最优比率生成树
    POJ 2976 Dropping tests 01分数规划 模板
    HDU 4081 Qin Shi Huang's National Road System 次小生成树变种
    HDU 4408 Minimum Spanning Tree 最小生成树计数
  • 原文地址:https://www.cnblogs.com/Benjamin-cpp/p/11844076.html
Copyright © 2011-2022 走看看