社区讨论
O(2^knk) 还能卡吗
P14362[CSP-S 2025] 道路修复参与者 4已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mhiybe08
- 此快照首次捕获于
- 2025/11/03 17:42 4 个月前
- 此快照最后确认于
- 2025/11/03 17:42 4 个月前
rt,just 80pts,最后几个点T了
CPP#include <bits/stdc++.h>
using namespace std;
#define il inline
#define pb emplace_back
typedef long long ll;
const int N = 3e6 + 10;
struct node
{
int u, v, w, id;
friend bool operator < (const node &n1, const node &n2)
{
return n1.w < n2.w;
}
}e[N], b[N];
int head[N], nxt[N], siz, f[N], c[11], a[11][N], n, m, k, tot;
unordered_map<int, int> mp;
il void add(int x, node y)
{
b[++siz] = y;
nxt[siz] = head[x];
head[x] = siz;
}
il int find(int x)
{
return f[x] == x ? x : f[x] = find(f[x]);
}
set<int> ss;
il ll kruskal(int x)
{
int nn = n + k;
ll mst = 0;
for(int i = 0;i < k;++i)
if((x >> i & 1)) mst += c[i];
for(int i = 1;i <= nn;++i) f[i] = i;
for(auto i : ss)
{
for(int j = head[i];j;j = nxt[j])
{
if(b[j].id != -1 && !((x >> b[j].id) & 1)) continue;
if(find(b[j].u) == find(b[j].v)) continue;
f[find(b[j].u)] = find(b[j].v);
mst += b[j].w;
}
}
return mst;
}
il int read()
{
char ch = getchar();
while(ch < 48 || ch > 57) ch = getchar();
int x = 0;
while(48 <= ch && ch <= 57)
{
x = (x << 1) + (x << 3) + ch - 48;
ch = getchar();
}
return x;
}
set<int> s;
int main()
{
n = read(), m = read(), k = read();
for(int i = 1;i <= m;++i)
{
e[i].u = read(), e[i].v = read(), e[i].w = read(), e[i].id = -1;
s.insert(e[i].w);
}
int tmp = 0;
for(int i = 0;i < k;++i)
{
c[i] = read();
tmp = max(tmp, c[i]);
for(int j = 1;j <= n;++j)
{
a[i][j] = read();
s.insert(a[i][j]);
}
}
for(auto i : s) mp[i] = ++tot;
for(int i = 1;i <= n;++i) f[i] = i;
sort(e + 1, e + 1 + m);
for(int i = 1;i <= m;++i)
{
if(find(e[i].u) == find(e[i].v)) continue;
add(mp[e[i].w], e[i]);
ss.insert(mp[e[i].w]);
f[find(e[i].u)] = find(e[i].v);
}
for(int i = 0;i < k;++i)
for(int j = 1;j <= n;++j)
add(mp[a[i][j]], (node){n + i + 1, j, a[i][j], i}), ss.insert(mp[a[i][j]]);
if(!tmp)
{
cout << kruskal((1 << k) - 1);
return 0;
}
ll ans = 1e18;
for(int i = 0;i < (1 << k);++i) ans = min(ans, kruskal(i));
cout << ans;
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...