P1111 修复公路
https://www.luogu.com.cn/problem/P1111
题目背景
A 地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。
题目描述
给出 A 地区的村庄数 N,和公路数 M,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)。
输入格式
第 1 行两个正整数 N,M。
下面 M行,每行 3 个正整数 x,y,t,告诉你这条公路连着 x,y 两个村庄,在时间t时能修复完成这条公路。
输出格式
如果全部公路修复完毕仍然存在两个村庄无法通车,则输出 -1,否则输出最早什么时候任意两个村庄能够通车。
class DSU:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self, x, y):
rootX = self.find(x)
rootY = self.find(y)
if rootX != rootY:
if self.rank[rootX] > self.rank[rootY]:
self.parent[rootY] = rootX
elif self.rank[rootX] < self.rank[rootY]:
self.parent[rootX] = rootY
else:
self.parent[rootY] = rootX
self.rank[rootX] += 1
return True
return False
def earliestAllConnected(N, M, roads):
dsu = DSU(N)
roads.sort(key=lambda x: x[2]) # 按修复时间排序
latestTime = 0
connectedComponents = N
for x, y, t in roads:
if dsu.union(x - 1, y - 1):
latestTime = max(latestTime, t)
connectedComponents -= 1
if connectedComponents == 1: # 所有村庄都连接起来了
return latestTime
if connectedComponents > 1:
return -1 # 仍然存在无法通车的村庄
return latestTime
# 从标准输入读取数据
N, M = map(int, input().split())
roads = [tuple(map(int, input().split())) for _ in range(M)]
# 输出结果
print(earliestAllConnected(N, M, roads))
P8783 统计子矩阵
题目描述
给定一个 N M 的矩阵 A,请你统计有多少个子矩阵 (最小 1*1 , 最大 N* M) 满足子矩阵中所有数的和不超过给定的整数 K。
输入格式
第一行包含三个整数 N, M 和 K。
之后 N 行每包含 M 个整数, 代表矩阵 A。
输出格式
一个整数代表答案。
int main() {
int n, m, k;
long long ans = 0; // 用于存储最终的答案
scanf_s("%d%d%d", &n, &m, &k); // 输入n, m, k
// 输入矩阵并计算前缀和
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
scanf_s("%d", &a[i][j]);
// 计算前缀和
s[i][j] = a[i][j] + s[i][j - 1] + s[i - 1][j] - s[i - 1][j - 1];
}
}
// 枚举所有可能的子矩阵,并统计满足条件的子矩阵数量
for (int i = 1; i <= n; ++i) {
for (int j = i; j <= n; ++j) {
for (int l = 1, r = 1; r <= m; ++r) {
// 调整左边界l,使得子矩阵的和不超过k
while (l <= r && s[j][r] - s[j][l - 1] - s[i - 1][r] + s[i - 1][l - 1] > k) {
++l;
}
// 统计数量
ans += (r - l + 1);
}
}
}
// 输出结果
printf("%lld\n", ans);
return 0;
}