zoukankan      html  css  js  c++  java
  • BZOJ3445: [Usaco2014 Feb] Roadblock

    数据范围很大,然而 n 很小

    可以料想最短路树也是很小的

    求最短路树,枚举最短路树上的树边,dijkstra 即可


    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cctype>
    #include<cstdio>
    #include<queue>
    using namespace std;
    
    typedef long long ll;
    const int MAXN = 255, MAXM = 250005;
    
    struct EDGE{
    	int nxt, to;
    	ll val;
    	EDGE(int NXT = 0, int TO = 0, ll VAL = 0ll) {nxt = NXT; to = TO; val = VAL;}
    }edge[MAXM << 1];
    int n, m, totedge = 1;
    int head[MAXN], pre[MAXN], frm[MAXN];
    bool vis[MAXN];
    ll org, ans, dst[MAXN];
    priority_queue<pair<ll,int> > q;
    
    inline void add(int x, int y, ll v) {
    	edge[++totedge] = EDGE(head[x], y, v);
    	head[x] = totedge;
    	return;
    }
    inline void dij() {
    	for(int i = 1; i <= n; ++i) dst[i] = 2000000000000000;
    	dst[1] = 0ll;
    	q.push(make_pair(0, 1));
    	while(!q.empty()) {
    		int x = q.top().second; q.pop();
    		if(vis[x]) continue;
    		vis[x] = true;
    		for(int i = head[x]; i; i = edge[i].nxt) {
    			register int y = edge[i].to;
    			if(dst[y] > dst[x] + edge[i].val) {
    				dst[y] = dst[x] + edge[i].val;
    				frm[y] = i;
    				pre[y] = x;
    				q.push(make_pair(-dst[y], y));
    			}
    		}
    	}
    	org = dst[n];
    	return;
    }
    inline void dij2() {
    	for(int i = 1; i <= n; ++i) dst[i] = 2000000000000000, vis[i] = false;
    	dst[1] = 0ll;
    	q.push(make_pair(0, 1));
    	while(!q.empty()) {
    		int x = q.top().second; q.pop();
    		if(vis[x]) continue;
    		vis[x] = true;
    		for(int i = head[x]; i; i = edge[i].nxt) {
    			register int y = edge[i].to;
    			if(dst[y] > dst[x] + edge[i].val) {
    				dst[y] = dst[x] + edge[i].val;
    				q.push(make_pair(-dst[y], y));
    			}
    		}
    	}
    	return;
    }
    inline void work() {
    	for(int y = 1; y <= n; ++y) {
    		int x = pre[y], i = frm[y];
    		edge[i].val <<= 1; edge[i ^ 1].val <<= 1;
    		dij2();
    		ans = max(ans, dst[n]);
    		edge[i].val >>= 1; edge[i ^ 1].val >>= 1;
    	}
    	return;
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	register int xx, yy;
    	register ll vv;
    	for(int i = 1; i <= m; ++i) {
    		scanf("%d%d%lld", &xx, &yy, &vv);
    		add(xx, yy, vv); add(yy, xx, vv);
    	}
    	dij();
    	work();
    	printf("%lld
    ", ans - org);
    	return 0;
    }
    

      

    禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载 ,用户转载请注明出处:https://www.cnblogs.com/xcysblog/
  • 相关阅读:
    【EFCORE笔记】自动生成属性的显式值
    【EFCORE笔记】更新数据的多种方案
    【EFCORE笔记】添加数据的多种方案
    【EFCORE笔记】多租户系统的最佳实践
    【EFCORE笔记】全局查询筛选器
    【EFCORE笔记】异步查询&工作原理&注释标记
    【EFCORE笔记】执行原始SQL查询
    003_Redis后台启动(windows10与)
    Office 2010后 如何保存新的样式集
    Mysql启动 发生系统错误 1067
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9583620.html
Copyright © 2011-2022 走看看