zoukankan      html  css  js  c++  java
  • 【POJ3613】Cow Relays

    题目链接:https://www.acwing.com/problem/content/347/

    题目大意:给定一张无向带权图 , 找出从 (s)(e) 恰好经过 (n) 条边的最短路径

    solution

    不难发现 , 顶点数可能很多 , 但边数不超过 100 , 因此对于节点编号应该先离散化一下

    用矩阵 (G^r) , 表示恰好经过 (r) 条边的最短路 , 其中 (G^r[i][j]) 表示从 (i)(j) 恰好经过 (r) 条边的最短路径 , 显然可以得出以下推论 :

    如果(r = p + q) , 则$$G^r[i][j] = min_{k leq n}left{G^p[i][k] + G^q[k][j] ight}(n为节点数量)$$

    同时发现 , 这个式子满足结合律 , 因此可以用矩阵快速幂快速求出 (G^r) , (G^n[s][e])即为题目所求

    时间复杂度: ((T^3logn))

    code

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T> inline void read(T &FF) {
    	int RR = 1; FF = 0; char CH = getchar();
    	for(; !isdigit(CH); CH = getchar()) if(CH == '-') RR = -RR;
    	for(; isdigit(CH); CH = getchar()) FF = FF * 10 + CH - 48;
    	FF *= RR;
    }
    inline void file(string str) {
    	freopen((str + ".in").c_str(), "r", stdin);
    	freopen((str + ".out").c_str(), "w", stdout);
    }
    const int N = 205;
    int n, m, s, e, path[N][3], ni, num[N];
    struct matrix{
    	int g[N][N];
    	matrix() {
    		memset(g, 0x3f, sizeof(g));
    		//for(int i = 1; i <= n; i++) g[i][i] = 0;
    	}
    	friend matrix operator * (const matrix &ai, const matrix &bi) {
    		matrix res;
    		for(int k = 1; k <= ni; k++)
    			for(int i = 1; i <= ni; i++)
    				for(int j = 1; j <= ni; j++)
    					res.g[i][j] = min(res.g[i][j], ai.g[i][k] + bi.g[k][j]);
    		return res;
    	}
    }base;
    void cpy(matrix &ai, const matrix &bi) {
    	for(int i = 1; i <= ni; i++)
    		for(int j = 1; j <= ni; j++)
    			ai.g[i][j] = bi.g[i][j];
    }
    matrix Qpow(int ki) {
    	if(ki == 1) return base;
    	matrix hi = Qpow(ki / 2); cpy(hi, hi * hi);
    	return ki & 1 ? hi * base : hi;
    }
    int main() {
    	//file("");
    	read(n), read(m), read(s), read(e);
    	for(int i = 1; i <= m; i++) {
    		read(path[i][0]), read(path[i][1]), read(path[i][2]);
    		num[++ni] = path[i][1], num[++ni] = path[i][2];
    	}
    	sort(num + 1, num + ni + 1);
    	ni = unique(num + 1, num + ni + 1) - num - 1;
    	//for(int i = 1; i <= n; i++) base.g[i][i] = 0;
    	for(int i = 1; i <= m; i++) {
    		path[i][1] = lower_bound(num + 1, num + ni + 1, path[i][1]) - num;
    		path[i][2] = lower_bound(num + 1, num + ni + 1, path[i][2]) - num;
    		base.g[path[i][1]][path[i][2]] = base.g[path[i][2]][path[i][1]] = path[i][0];
    	}
    	s = lower_bound(num + 1, num + ni + 1, s) - num;
    	e = lower_bound(num + 1, num + ni + 1, e) - num;
    	matrix ans = Qpow(n);
    	cout << ans.g[s][e] << endl;
    	return 0;
    }
    
  • 相关阅读:
    RabbitMQ WindowServer2008R2 安装配置
    wpf的低调自定义属性面板PropertyGrid
    复旦大学2020--2021学年第二学期高等代数II期末考试情况分析
    复旦大学2020--2021学年第二学期(20级)高等代数II期末考试第七大题解答
    复旦大学2020--2021学年第二学期(20级)高等代数II期末考试第八大题解答
    复旦高等代数II(20级)每周一题
    复旦大学高等代数课程介绍
    consul 下线服务 服务注销脚本
    consul 集群搭建
    Linux Limit相关内容设置大全(值得收藏)
  • 原文地址:https://www.cnblogs.com/magicduck/p/12241818.html
Copyright © 2011-2022 走看看