修路

【问题描述】

村子间的小路年久失修,为了保障村子之间的往来,法珞决定带领大家修路。对于边带权的无向图 G = (V, E),请选择一些边,使得1 <= i <= d, i号节点和 n - i + 1 号节点可以通过选中的边连通,最小化选中的所有边的权值和。

【输入格式】

第一行两个整数 n, m,表示图的点数和边数。接下来的 m行,每行三个整数 ui, vi, wi,表示有一条 ui 与 vi 之间,权值为 wi 的无向边。

【输出格式】

一行一个整数,表示答案,如果无解输出-1

【样例输入】

10 20 1
6 5 1
6 9 4
9 4 2
9 4 10
6 1 2
2 3 6
7 6 10
5 7 1
9 7 2
5 9 10
1 6 8
4 7 4
5 7 1
2 6 9
10 10 6
8 7 2
10 9 10
1 2 4
10 1 8
9 9 7

【样例输出】

8

【数据范围】

1 <= d <= 4
2d <= n <= 10^4
0 <= m <= 10^4
1 <= ui, vi <= n
1 <= wi <= 1000

题解:

考虑到d灰常小,就是斯坦纳树啦

用斯坦纳树求出以u为根,连通情况为opt的最小价值,记为f[u][opt]

由于题目只要 i 与 n - i + 1 连通,那么取出所有对称的opt,取最小值,记为ans[opt]

再暴力Dp合并

 #include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
inline void Scan(int &x)
{
char c;
while((c = getchar()) < '' || c > '');
x = c - '';
while((c = getchar()) >= '' && c <= '') x = x * + c - '';
}
const int maxn = ;
const int inf = ;
int n, m, d, t, w;
int num, all;
bool vis[maxn];
int ans[], que[maxn];
int f[maxn][];
int tot, nex[maxn], fir[maxn], ver[maxn], pri[maxn];
inline void Ins(int x, int y, int z)
{
nex[++tot] = fir[x];
fir[x] = tot;
ver[tot] = y;
pri[tot] = z;
}
inline void Reset()
{
memset(f, / , sizeof(f));
for(int i = ; i <= d; ++i) f[i][ << num++] = ;
for(int i = n - d + ; i <= n; ++i) f[i][ << num++] = ;
all = << num;
}
inline void Spfa(int opt)
{
t = ;
while(t < w)
{
int u = que[++t];
for(int i = fir[u]; i; i = nex[i])
{
int v = ver[i];
if(f[u][opt] + pri[i] < f[v][opt])
{
f[v][opt] = f[u][opt] + pri[i];
if(!vis[v])
{
vis[v] = true;
que[++w] = v;
}
}
}
vis[u] = false;
}
}
int main()
{
Scan(n), Scan(m), Scan(d);
int x, y, z;
for(int i = ; i <= m; ++i)
{
Scan(x), Scan(y), Scan(z);
Ins(x, y, z), Ins(y, x, z);
}
Reset();
for(int opt = ; opt < all; ++opt)
{
w = ;
for(int i = ; i <= n; ++i)
{
for(int sub = opt; sub; sub = (sub - ) & opt)
f[i][opt] = min(f[i][opt], f[i][sub] + f[i][opt ^ sub]);
if(f[i][opt] != inf) que[++w] = i, vis[i] = true;
}
Spfa(opt);
ans[opt] = inf;
}
bool flag;
for(int opt = ; opt < all; ++opt)
{
flag = false;
for(int i = ; i <= d; ++i)
{
bool a = (opt & ( << i)) != ;
bool b = (opt & ( << (d << ) - i - )) != ;
if(a != b)
{
flag = true;
break;
}
}
if(flag) continue;
for(int i = ; i <= n; ++i) ans[opt] = min(ans[opt], f[i][opt]);
}
for(int opt = ; opt < all; ++opt)
for(int sub = opt; sub; sub = (sub - ) & opt)
ans[opt] = min(ans[opt], ans[sub] + ans[opt ^ sub]);
if(ans[all - ] != inf) printf("%d", ans[all - ]);
else printf("-1");
}

修路 BZOJ 4774的更多相关文章

  1. bzoj 4774: 修路

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 282  Solved: 132[Submit][Status][Discuss] Descriptio ...

  2. 【BZOJ4774】修路(动态规划,斯坦纳树)

    [BZOJ4774]修路(动态规划,斯坦纳树) 题面 BZOJ 题解 先讲怎么求解最小斯坦纳树. 先明白什么是斯坦纳树. 斯坦纳树可以认为是最小生成树的一般情况.最小生成树是把所有给定点都要加入到联通 ...

  3. bzoj4774 修路

    4774: 修路 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 290  Solved: 137[Submit][Status][Discuss] D ...

  4. bzoj 1196 公路修建问题

    bzoj 1196: [HNOI2006]公路修建问题 Description OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情 ...

  5. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  6. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  7. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  8. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  9. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

随机推荐

  1. iOS上架问题解决

    dns问题 http://iphone.91.com/tutorial/syjc/140509/21686339.html 网络问题 手机4g开wifi,上传提交多次 时间问题 东八区下午6点上架成功 ...

  2. windows定时任务小注

    static class Program { /// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static vo ...

  3. 用python编写九九乘法表

    for i in range(1,10): for j in range(1,10): if j >i: print(end='') else: print(j,'*',i,'=',i*j,en ...

  4. nyoj-586-疯牛|poj-2456-Aggressive cows

    http://acm.nyist.net/JudgeOnline/problem.php?pid=586 http://poj.org/problem?id=2456 解题思路:最大化最小值二分答案即 ...

  5. PAT (Basic Level) Practise (中文)-1035. 插入与归并(25)

    PAT (Basic Level) Practise (中文)-1035. 插入与归并(25)   http://www.patest.cn/contests/pat-b-practise/1035 ...

  6. UNIX 进程间通讯(IPC)概念(Posix,System V IPC)

     IPC(Inter-Process Communication,进程间通讯)可以有三种信息共享方式(随文件系统,随内核,随共享内存).(当然这里虽然说是进程间通讯,其实也是可以和线程相通的). 相对 ...

  7. Python3 try-except、raise和assert解析

    Python3 try-except.raise和assert解析 一.说明 关于异常捕获try-except:在学java的时候就被教育异常捕获也是java相对c的一大优点,几年下来多少也写了些代码 ...

  8. struct 区别 在C 和C++ 中

    C语言中:   Struct是用户自定义数据类型(UDT).   C++语言中:   Struct是抽象数据类型(ADT),支持成员函数的定义.       在C++中,struct的成员的默认访问说 ...

  9. 【php】 自带的过滤机制

    <?php print_r(filter_list()); ?> 输出类似: Array ( [0] => int [1] => boolean [2] => float ...

  10. php各种主流框架的优缺点总结

    ThinkPHP ThinkPHP(FCS)是一个轻量级的中型框架,是从Java的Struts结构移植过来的中文PHP开发框架.它使用面向对象的开发结构和MVC模式,并且模拟实现了Struts的标签库 ...