# [BZOJ4006][JLOI2015]管道连接

### [BZOJ4006][JLOI2015]管道连接

#### 输入示例

5 8 4
1 2 3
1 3 2
1 5 1
2 4 2
2 5 1
3 4 3
3 5 1
4 5 1
1 1
1 2
2 3
2 4


#### 输出示例

4


#### 题解

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i++)
#define dwn(i, s, t) for(int i = (s); i >= (t); i--)

const int BufferSize = 1 << 16;
inline char Getchar() {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
}
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
}

#define maxn 1010
#define maxp 15
#define maxm 6010
#define maxs 1024
#define oo 2147483647

int n, m, p, head[maxn], nxt[maxm], to[maxm], dist[maxm], col[maxp];

void AddEdge(int a, int b, int c) {
to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
swap(a, b);
to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
return ;
}

#define D f[Set]
struct Node {
int u, d;
Node() {}
Node(int _, int __): u(_), d(__) {}
bool operator < (const Node& t) const { return d > t.d; }
};
priority_queue <Node> Q;
int f[maxs][maxn];
bool vis[maxn];
void ShortPath(int Set) {
memset(vis, 0, sizeof(vis));
rep(i, 1, n) if(D[i] < oo) Q.push(Node(i, D[i]));
while(!Q.empty()) {
int u = Q.top().u; Q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int e = head[u]; e; e = nxt[e]) if(D[to[e]] > D[u] + dist[e]) {
D[to[e]] = D[u] + dist[e];
if(!vis[to[e]]) Q.push(Node(to[e], D[to[e]]));
}
}
return ;
}

int F[maxs], ans[maxs];

int main() {
rep(i, 1, M) {
}

int all = (1 << p) - 1;
rep(s, 0, all) rep(i, 1, n) f[s][i] = oo;
rep(i, 0, p - 1) {
}
rep(s, 0, all) {
rep(i, 1, n)
for(int ts = (s - 1 & s); ts; ts = (ts - 1 & s))
f[s][i] = min(f[s][i], f[ts][i] + f[s^ts][i]);
ShortPath(s);
}

rep(s, 0, all) {
F[s] = oo;
rep(i, 1, n) F[s] = min(F[s], f[s][i]);
}
rep(s, 0, all) {
ans[s] = F[s];
for(int ts = (s - 1 & s); ts; ts = (ts - 1 & s)) {
int Col = 0, Cor = 0;
rep(i, 0, p - 1)
if(ts >> i & 1) Col |= (1 << col[i] - 1);
else Cor |= (1 << col[i] - 1);
if(Col & Cor) continue;
ans[s] = min(ans[s], F[ts] + F[s^ts]);
}
}

printf("%d\n", ans[all]);

return 0;
}

posted @ 2017-12-07 15:45  xjr01  阅读(166)  评论(0编辑  收藏