# 【BZOJ4006】【JLOI2015】管道连接

【题目链接】

【思路要点】

• 补档博客，无题解。

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXQ	1000005
#define MAXN	1005
#define CURR	1024
#define INF	1e9
struct edge {int dest, len; };
vector <edge> a[MAXN];
int n, m, p, num[MAXN], c[MAXN], d[MAXN];
int ans[MAXN][CURR], opt[CURR];
bool inq[MAXN][CURR];
int main() {
ios::sync_with_stdio(false);
cin >> n >> m >> p;
for (int i = 1; i <= m; i++) {
int x, y, z;
cin >> x >> y >> z;
a[x].push_back((edge) {y, z});
a[y].push_back((edge) {x, z});
}
int tot = 0;
for (int i = 1; i <= p; i++) {
cin >> c[i] >> d[i];
num[d[i]] = ++tot;
}
for (int i = 1; i <= n; i++)
for (int j = 1; j < 1 << p; j++)
if (num[i] && j == 1 << num[i] - 1) ans[i][j] = 0;
else ans[i][j] = INF;
for (int curr = 1; curr < 1 << p; curr++) {
static int qx[MAXQ], qy[MAXQ];
int l = 0, r = -1;
for (int i = 1; i <= n; i++) {
for (int j = (curr - 1) & curr; j; j = (j - 1) & curr)
ans[i][curr] = min(ans[i][curr], ans[i][j] + ans[i][curr ^ j]);
if (ans[i][curr] < INF) {
inq[i][curr] = true;
qx[++r] = i;
qy[r] = curr;
}
}
while (l <= r) {
int tx = qx[l], ty = qy[l++];
inq[tx][ty] = false;
for (unsigned i = 0; i < a[tx].size(); i++)
if (ans[tx][ty] + a[tx][i].len < ans[a[tx][i].dest][ty]) {
ans[a[tx][i].dest][ty] = ans[tx][ty] + a[tx][i].len;
if (!inq[a[tx][i].dest][ty]) {
qx[++r] = a[tx][i].dest;
qy[r] = ty;
inq[qx[r]][qy[r]] = true;
}
}
}
}
for (int i = 0; i < 1 << p; i++) {
int tmp = 0;
for (int j = 1; j <= p; j++)
if (i & (1 << c[j] - 1)) tmp |= 1 << num[d[j]] - 1;
opt[i] = INF;
for (int j = 1; j <= n; j++)
opt[i] = min(opt[i], ans[j][tmp]);
for (int j = (i - 1) & i; j; j = (j - 1) & i)
opt[i] = min(opt[i], opt[j] + opt[i ^ j]);
}
int goal = 0;
for (int i = 1; i <= p; i++)
goal |= 1 << c[i] - 1;
cout << opt[goal] << endl;
return 0;
}

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客