ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

1120考试T2

2020-11-20 21:35:24  阅读:217  来源: 互联网

标签:ch 1120 T2 机器人 矩阵 long read 12 考试


1120考试T2

​ 题目大意:

​ 给你一个n个点,m条边的图,每条边有一个权值在某几个时刻有一些点不能走,每次必须走一条边,求恰好k时刻到达终点的路径中最大边权最小.

​ 其中不能走的点是这样的: 有\(num\)个机器人, 每个机器人会周期性的按顺序走一些点, 编号为\(t_1, t_2, ...\)

​ \(n <= 50, m <= 1600, k <= 1e8, num <= 10, t_i <= 4\)

与这道题很像, 只不过这道题求方案数

​ 矩阵快速幂.

​ 我们发现\(t\)最大只有4, 得出这些机器人最多只会有12种所在点的状态, 也就是12个一循环.

​ 那么我们可以处理出这12个矩阵, 也就是在这些状态下那些点不能走, 然后把这12个矩阵相乘, 就得到了一次循环后, 各点之间路径的最大边权最小值.

​ 然后我们把这个乘后的矩阵作为转移矩阵, 用矩阵快速幂, 那么指数就应该是\(k / 12\).

​ 对于剩下的\(k \% 12\)次暴力乘就好了.

​ 复杂度\(O(n^2log \ k)\)

#include <bits/stdc++.h>

using namespace std;

inline long long read() {
	long long s = 0, f = 1; char ch;
	while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
	return s * f;
}

const int N = 55, inf = 1e9;
int n, m, k, s, t, num;
int a[N], now[N], dis[N][N], num_a[N];
struct mat { 
	int v[N][N]; 
	void init() { for(int i = 1;i <= n; i++) for(int j = 1;j <= n; j++) v[i][j] = inf; }
	void with_dis() { for(int i = 1;i <= n; i++) for(int j = 1;j <= n; j++) v[i][j] = dis[i][j]; }
} ans, turn, q[13];

mat operator * (const mat &a, const mat &b) {
	mat c; c.init();
	for(int i = 1;i <= n; i++)
		for(int j = 1;j <= n; j++)
			for(int k = 1;k <= n; k++) 
				if(a.v[i][k]) c.v[i][j] = min(c.v[i][j], max(a.v[i][k], b.v[k][j]));
	return c;
}

mat ksm(mat x, int y) {
	mat res; res.init();
	for(int i = 1;i <= n; i++) res.v[i][i] = 1;
	while(y) { if(y & 1) res = res * x; x = x * x; y >>= 1; }
	return res;
}

int main() {

	n = read(); m = read(); k = read();
	if(m == 0 && k == 0) { printf("0"); return 0; }
	for(int i = 1;i <= n; i++)
		for(int j = 1;j <= n; j++) dis[i][j] = inf;
	for(int i = 1, x, y, z;i <= m; i++) {
		x = read(); y = read(); z = read();
		if(dis[x][y]) dis[x][y] = dis[y][x] = min(dis[x][y], z);
		else dis[x][y] = dis[y][x] = z;
	}
	for(int i = 1;i <= 12; i++) q[i].with_dis();
	num = read(); s = read(); t = read(); ans.init();
	for(int i = 1, x;i <= num; i++) {
		x = read();
		for(int j = 1;j <= x; j++) a[j] = read();
		for(int j = 1;j <= 12; j++) {
			int p = a[j % x == 0 ? x : j % x];
			for(int l = 1;l <= n; l++) q[j].v[l][p] = inf;
		}
	}
	turn = q[1];
	for(int i = 2;i <= 12; i++) turn = turn * q[i];
	ans = ksm(turn, k / 12);
	for(int i = 1;i <= k % 12; i++) ans = ans * q[i];
	if(ans.v[s][t] == 1e9) printf("impossible");
	else printf("%d", ans.v[s][t]);

	return 0;
}

标签:ch,1120,T2,机器人,矩阵,long,read,12,考试
来源: https://www.cnblogs.com/czhui666/p/14013116.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有