【斯坦纳树】 HDOJ 3311 Dig The Wells
2015-02-10 20:00
316 查看
题意:给出n+ m个点,点权,再给出m2条边,边权。求n个点各自能喝道水的最小代价。
解题思路:DP过程增加一维,代表能不能喝到水,做一边斯坦纳树,然后再做一边DP。
解题思路:DP过程增加一维,代表能不能喝到水,做一边斯坦纳树,然后再做一边DP。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 1009 #define maxm 10005 #define eps 1e-7 #define mod 1000000007 #define INF 0x3f3f3f3f #define PI (acos(-1.0)) #define lowbit(x) (x&(-x)) #define mp make_pair #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R #define pii pair<int, int> #pragma comment(linker, "/STACK:16777216") typedef long long LL; typedef unsigned long long ULL; //typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} // head struct Edge { int v, w; Edge *next; }*H[maxn], *edges, E[maxm]; struct node { int x, y, k; node() {} node(int x, int y, int k) : x(x), y(y), k(k) {} }; queue<node> q; int c[maxn]; int p[maxn]; int dp[maxn]; int d[maxn][1 << 6][2]; int in[maxn][1 << 6][2]; int n, m, m2, o; void addedges(int u, int v, int w) { edges->v = v; edges->w = w; edges->next = H[u]; H[u] = edges++; } void init() { edges = E; memset(H, 0, sizeof H); memset(p, 0, sizeof p); memset(d, INF, sizeof d); memset(dp, INF, sizeof dp); } void read() { int u, v, w; for(int i = 1; i <= n + m; i++) scanf("%d", &c[i]); while(m2--) { scanf("%d%d%d", &u, &v, &w); addedges(u, v, w); addedges(v, u, w); } o = 1 << n; for(int i = 1; i <= n; i++) { p[i] = 1 << i - 1; d[i][p[i]][0] = 0; d[i][p[i]][1] = c[i]; } } void spfa() { while(!q.empty()) { int x = q.front().x, y = q.front().y, k = q.front().k; q.pop(), in[x][y][k] = false; for(Edge *e = H[x]; e; e = e->next) { int v = e->v, w = e->w; if(!k) { if(d[v][y | p[v]][0] > d[x][y][0] + w) { d[v][y | p[v]][0] = d[x][y][0] + w; if(!in[v][y | p[v]][0]) { in[v][y | p[v]][0] = true; q.push(node(v, y | p[v], 0)); } } if(d[v][y | p[v]][1] > d[x][y][0] + w + c[v]) { d[v][y | p[v]][1] = d[x][y][0] + w + c[v]; if(!in[v][y | p[v]][1]) { in[v][y | p[v]][1] = true; q.push(node(v, y | p[v], 1)); } } } else { if(d[v][y | p[v]][1] > d[x][y][1] + w) { d[v][y | p[v]][1] = d[x][y][1] + w; if(!in[v][y | p[v]][1]) { in[v][y | p[v]][1] = true; q.push(node(v, y | p[v], 1)); } } } } } } void work() { for(int y = 0; y < o; y++) { for(int x = 1; x <= n + m; x++) { for(int i = (y - 1) & y; i; i = (i - 1) & y) { d[x][y][0] = min(d[x][y][0], d[x][y - i | p[x]][0] + d[x][i | p[x]][0]); d[x][y][1] = min(d[x][y][1], d[x][y - i | p[x]][1] + d[x][i | p[x]][0]); d[x][y][1] = min(d[x][y][1], d[x][y - i | p[x]][0] + d[x][i | p[x]][1]); // d[x][y][1] = min(d[x][y][1], d[x][y - i | p[x]][1] + d[x][i | p[x]][1]); } if(d[x][y][0] < INF) q.push(node(x, y, 0)), in[x][y][0] = true; if(d[x][y][1] < INF) q.push(node(x, y, 1)), in[x][y][1] = true; } spfa(); } for(int i = 0; i < o; i++) for(int j = 1; j <= n + m; j++) dp[i] = min(dp[i], d[j][i][1]); for(int i = 0; i < o; i++) for(int j = (i - 1) & i; j; j = (j - 1) & i) dp[i] = min(dp[i], dp[i - j] + dp[j]); printf("%d\n", dp[o - 1]); } int main() { while(scanf("%d%d%d", &n, &m, &m2)!=EOF) { init(); read(); work(); } return 0; }
相关文章推荐
- HDOJ 3311 Dig The Wells
- Hdu 3311 Dig The Wells (综合_斯坦纳树)
- 【HDOJ】3311 Dig The Wells
- HDU 3311 Dig The Wells(斯坦纳树)
- HDU 3311 Dig The Wells(spfa模板)
- HDU 3311 Dig The Wells
- hdu3311 - Dig The Wells (斯坦纳树 spfa + DP)
- hdu 3311 Dig The Wells (SteinerTree斯坦纳树)
- HDU-3311-Dig The Wells
- hdu3311 Dig The Wells(斯坦纳树dp)
- HDU3311-Dig The Wells
- 【HDOJ】1699 The comment in cpp
- HDOJ 题目3336Count the string(kmp)
- HDOJ 1048 The Hardest Problem Ever(加密解密类)
- hdoj 1596 find the safest road【最短路变形,求最大安全系数】
- hdoj 4006 The kth great number
- hdoj--1028--Ignatius and the Princess III(母函数)
- Hie with the Pie - POJ 3311 状压dp
- hdoj 2438 Turn the corner
- hdoj 1115 Lifting the Stone (求多边形重心)