zoukankan      html  css  js  c++  java
  • [洛谷P4822][BJWC2012]冻结

    题目大意:有一张$n(nleqslant50)$个点$m(mleqslant1000)$条边的无向图,可以使得$k$条边使得边权减半,求最短路

    题解:分层图最短路

    卡点:

    C++ Code:

    #include <cstdio>
    #include <cstring>
    #define maxn 52
    #define maxm 1010
    #define maxk 51
    #define N (maxn * maxk)
    #define M (maxm * maxk * 2)
    
    int head[N], cnt;
    struct Edge {
    	int to, nxt, w;
    } e[M << 1];
    inline void addedge(int a, int b, int c) {
    	e[++cnt] = (Edge) {b, head[a], c}; head[a] = cnt;
    }
    inline void addedge2(int a, int b, int c) {
    	addedge(a, b, c);
    	addedge(b, a, c);
    }
    
    int n, m, k, nn;
    const int inf = 0x3f3f3f3f;
    int dis[N];
    inline int getmin(int a, int b) { return dis[a] < dis[b] ? a : b; }
    
    namespace SgT {
    	int V[N << 2];
    	void modify(int rt, int l, int r, int pos, int num) {
    		if (l == r) {
    			V[rt] = num;
    			return ;
    		}
    		const int mid = l + r >> 1;
    		if (pos <= mid) modify(rt << 1, l, mid, pos, num);
    		else modify(rt << 1 | 1, mid + 1, r, pos, num);
    		V[rt] = getmin(V[rt << 1], V[rt << 1 | 1]);
    	}
    }
    int dijkstra(int S, int T) {
    	memset(dis, 0x3f, sizeof dis);
    	dis[S] = 0; SgT::modify(1, 1, nn, S, S);
    	for (int Tim = nn; Tim; --Tim) {
    		int u = SgT::V[1];
    		SgT::modify(1, 1, nn, u, 0);
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to;
    			if (dis[v] > dis[u] + e[i].w) {
    				dis[v] = dis[u] + e[i].w;
    				SgT::modify(1, 1, nn, v, v);
    			}
    		}
    	}
    	return dis[T];
    }
    
    int main() {
    	scanf("%d%d%d", &n, &m, &k); nn = n * k + n;
    	for (int i = 0, a, b, c; i < m; ++i) {
    		scanf("%d%d%d", &a, &b, &c);
    		for (int j = 0; j <= k; ++j) {
    			addedge2(j * n + a, j * n + b, c);
    			if (j) {
    				addedge((j - 1) * n + a, j * n + b, c >> 1);
    				addedge((j - 1) * n + b, j * n + a, c >> 1);
    			}
    		}
    	}
    	for (int i = 0; i < k; i++) addedge(i * n + n, (i + 1) * n + n, 0);
    	printf("%d
    ", dijkstra(1, k * n + n));
    	return 0;
    }
    

      

  • 相关阅读:
    ANDROIDSTUDIO手动安装插件
    xcode 升级到最新的11.1版本打开项目卡顿解决方案
    OC各种数据类型之间的转换方法
    TOJ 3365 ZOJ 3232 It's not Floyd Algorithm / 强连通分量
    在linux下makefile的使用
    Binary Search二分法搜索C++程序
    ORA-01654错误
    合作版状态模式之设计
    基于FPGA的超声波测距(一)
    如何随机获取数据库不连续ID的数据?
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10225242.html
Copyright © 2011-2022 走看看