题解:P11892 [XRCOI Round 1] C. 草萤有耀终非火
题目大意
有一个
若存在正整数
目标:最终使
思路
4 pts
若
若任意两个燃料格子既不在同一行也不在同一列,则同样输出
20 pts
采用暴力搜索枚举所有可能情况。
AC 做法
从题目描述中可以感受到,本题与矩形的性质密切相关。目标点
这样一来,问题就转化为:将第
对于三个终端节点,最小斯坦纳树的大小等价于
具体实现时,我们分别以这三个节点为源点,进行三次 BFS(图中每条边权均为
代码
这里我习惯用链式前向星存图,应该是比 vector 的做法要快一点。
::::info[代码]
/*
By Nongwu_
2026 / 8 / 7
给个关注呗 QwQ
不给关注给个赞也彳亍 TwT
*/
#include<bits/stdc++.h>
#define Nongwu_ 0
#define By return
using namespace std;
using ll = long long ;
const int N = 2e5 + 10, INF = INT_MAX, M = 2e6 + 10;
int t, n, m, k;
int tot, head[N];
ll len[N], sum[N];
queue<int> q;
struct Edge{
int next, to;
} e[M << 1];
void add(int x, int y) {
e[++tot] = {head[x], y};
head[x] = tot;
}
void bfs(int root) {
for (int i = 1; i <= n + m; ++i)
len[i] = INF; //多测一定要清空口牙
q.push(root);
len[root] = 0;
while (!q.empty()) {
int x = q.front();
q.pop();
for (int i = head[x]; i; i = e[i].next) {
int y = e[i].to;
if (len[y] == INF) {
len[y] = len[x] + 1;
q.push(y);
}
}
}
for (int i = 1; i <= n + m; ++i)
sum[i] += len[i];
}
void solve() {
tot = 0;
for (int i = 1; i <= n + m; ++i) { //多测清空
head[i] = 0;
sum[i] = 0;
}
cin >> n >> m >> k;
for (int i = 1, x, y; i <= k; ++i) {
cin >> x >> y;
add(x, y + n);
add(y + n, x);
}
bfs(1);
bfs(n + 1);
bfs(n + m);
ll ans = INF;
for (int i = 1; i <= n + m; ++i)
ans = min(ans, sum[i]);
if (ans < INF)
cout << ans << '\n';
else
cout << "-1\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> t;
while (t--)
solve();
By Nongwu_;
}
::::
本文章经过 Deepseek 润色,作者保证本人贡献绝对大于 AI。