HDU4085 斯坦纳树
来源:互联网 发布:杭州紫府网络 编辑:程序博客网 时间:2024/04/27 15:22
http://acm.hdu.edu.cn/showproblem.php?pid=4085
新学习了斯坦纳树,记录一下。
我是从http://endlesscount.blog.163.com/blog/static/821197872012525113427573/学习的斯坦纳树
斯坦纳树用于解决保证指定节点连接的情况下,求边权总和最小的问题。算是用最短路辅助的DP问题
斯坦纳树核心部分:
for(int state = 0; state < endState; state++){ for(int root = 1; root <= n; root++){ for (int sub = (state-1)&state; sub; sub = (sub-1)&state){ mincost[root][state] = min(mincost[root][state], mincost[root][sub|st[root]] + mincost[root][(state-sub)|st[root]]); } if(mincost[root][state] < INF){ isVis[root][state] = true; que.push(root*base+state); } } spfa(); }
mincost[root][state] 表示以root为根,连接状态为state构造出来的图的边权总和, sub 是 state 的子状态
spfa部分:
void spfa(){ while(!que.empty()){ int now = que.front(); que.pop(); int root = now / base; int state = now % base; isVis[root][state] = false; for (int k = head[root]; k != -1; k = edges[k].next){ int to = edges[k].to, weight = edges[k].length; if (update(to, state|st[to], mincost[root][state] + weight) && state|st[to] == state && !isVis[to][state]) isVis[to][state] = true; que.push(to*base + state); } }}
AC代码:
#include<bits/stdc++.h>using namespace std;const int INF = 1e6+10;int n, m, K, endSt, tot;int mincost[55][1<<11], st[55];int dp[1<<11];int head[55];bool vis[55][1<<11];queue<int> que;struct Edge{ int to, length; int next; Edge(){} Edge(int t, int len){ to = t; length = len; next = -1; }}edges[2005];void addEdge(int from, int to, int len){ edges[++tot] = Edge(to, len); edges[tot].next = head[from]; head[from] = tot;}void input(){ tot = 0; memset(head, -1, sizeof(head)); memset(vis, false, sizeof(vis)); memset(st, 0, sizeof(st)); scanf("%d%d%d", &n, &m, &K); for (int i = 0; i < m; i++){ int from, to, len; scanf("%d%d%d", &from, &to, &len); addEdge(from, to, len); addEdge(to, from, len); } endSt = 1<<(2*K); for (int i = 1; i <= n; i++){ for (int j = 0; j < endSt; j++){ mincost[i][j] = INF; } } for (int i = 1; i <= K; i++){ st[i] = 1<<(i-1); mincost[i][st[i]] = 0; st[n-i+1] = 1<<(K+i-1); mincost[n-i+1][st[n-i+1]] = 0; } while(!que.empty()) que.pop();}bool check(int state){ int res = 0; for (int i = 0; state; i++, state>>=1){ res += (state&1)*(i < K ? 1 : -1); } return res == 0;}bool update(int root, int state, int weight){ if (weight < mincost[root][state]){ mincost[root][state] = weight; return true; } return false;}void spfa(){ while(!que.empty()){ int now = que.front(); que.pop(); int root = now / 10000; int state = now % 10000; vis[root][state] = false; for (int k = head[root]; k != -1; k = edges[k].next){ int to = edges[k].to, weight = edges[k].length; if (update(to, state|st[to], mincost[root][state]+weight) && state == (state|st[to]) && !vis[to][state]){ vis[to][state] = true; que.push(to*10000+state); } } }}int main(){ int T; scanf("%d",&T); while(T--){ input(); for (int state = 0; state < endSt; state++){ for (int root = 1; root <= n; root++){ for (int sub = (state-1)&state; sub; sub = (sub-1)&state){ mincost[root][state] = min(mincost[root][state], mincost[root][sub|st[root]] + mincost[root][(state-sub)|st[root]]); } if (mincost[root][state] < INF){ que.push(root*10000+state); vis[root][state] = true; } } spfa(); } for (int state = 0; state < endSt; state++){ dp[state] = INF; for (int root = 1; root <= n; root++){ dp[state] = min(mincost[root][state], dp[state]); } } for (int state = 1; state < endSt; state++){ if (!check(state)) continue; for (int sub = (state-1)&state; sub; sub = (sub-1)&state){ if (!check(sub)) continue; dp[state] = min(dp[state], dp[sub] + dp[state-sub]); } } if (dp[endSt-1] >= INF) printf("No solution\n"); else printf("%d\n", dp[endSt-1]); } return 0;}
0 0
- 斯坦纳树 hdu4085
- HDU4085【斯坦纳树】
- HDU4085 斯坦纳树
- hdu4085 斯坦纳森林
- 【HDU4085】Peach Blossom Spring【斯坦纳树】【状态压缩】
- [HDU4085]Peach Blossom Spring(斯坦纳树+dfs)
- hdu4085 Peach Blossom Spring (斯坦纳树,状态dp)spfa
- 斯坦纳树
- 斯坦纳树
- 斯坦纳树
- BZOJ4006【斯坦纳树】
- 【模板】斯坦纳树
- 斯坦纳树问题
- 斯坦纳生成树
- 【模板】斯坦纳树
- 斯坦纳树
- hdu6060斯坦纳树
- 斯坦纳树 Steiner Tree
- 算法之冒泡排序
- Ubuntu 16.04 DSO 试运行
- HDUAcm(1872)--稳定排序
- install ftp server on centos6
- python语言 根据数据文件 在窗口中绘制路径 要点
- HDU4085 斯坦纳树
- python读书笔记(一)
- centos7.1下php7安装redis扩展
- file struct 利用总结——百度杯总决赛线上赛try to pwn write up
- 1021. Deepest Root (25)
- 对象的软、弱、虚引用
- 推荐的重构之引发对架构思考
- Navicat连接MySQL报错
- HDU2203:亲和串(KMP)