Description

题目链接

求一张无向带权图的边双连通生成子图的最小代价。

Solution

核心的思路是,一个点双连通分量肯定是一堆环的并。

考虑增量地构造这个边双连通图,每次把一个环并进去,相当于加入了一条链。

那么这个转移需要:原集合的代价,链的代价,链的端点连入集合的代价。

设 \(A\) 为新图点集,\(S\) 为原图点集,设 \(f[S]\) 表示点集 \(S\) 构成边双连通分量的最小代价。

设 \(T\) 为新加入链的点集,\(u,v\) 分别为加入的链的端点,设 \(g[u][v][T]\) 表示该链的最小代价。

设 \(mm[u][S]\) 表示点 \(u\) 向集合 \(S\) 中的点所连边中,边权最小值。

\[f[A]=f[S]+g[u][v][T]+mn[u][S]+mn[v][S]
\]

但是注意,如果新加入的链退化成了一个点,加入的代价就算少了。

因此设 \(sec[u][S]\) 表示点 \(u\) 向集合 \(S\) 中的点所连边中,边权次小值。

那么对于 \(u=v\) 的情况:

\[f[A]=f[S]+g[u][u][T]+mn[u][S]+sec[u][S]
\]

预处理 \(mn\) 和 \(sec\) 复杂度 \(\mathcal O(n^2\times 2^n)\)

预处理 \(g\) 暴力枚举一个端点的变化,复杂度 \(\mathcal O(n^3\times 2^n)\)

计算 \(f\) 需要枚举子集,然后枚举 \(u, v\) ,复杂度 \(\mathcal O(n^2\times 3^n )\)

#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 15
#define M 105
#define S 4105
using namespace std; inline int rd() {
int x = 0;
char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) {
x = x * 10 + (c ^ 48); c = getchar();
}
return x;
} int n, m, tot, lim, hd[N]; struct edge{int w, to, nxt;} e[M << 1]; inline void add(int u, int v, int w) {
e[++tot].to = v; e[tot].w = w;
e[tot].nxt = hd[u]; hd[u] = tot;
} //mn[i][S]: i 到 S 最短路
//sec[i][S]: i 到 S 次短路
//g[i][j][S]: 一条链,节点集合为 S, 端点分别为 i, j
//f[S]: 集合为 S 的合法方案 int f[S], g[N][N][S], mn[N][S], sec[N][S]; inline void mmin(int &x, int y) {x = min(x, y);} inline int countbit(int s) {
int res = 0;
for (int i = 0; i < n; ++i)
res += ((s & (1 << i)) > 0);
return res;
} inline void work() {
n = rd(); m = rd();
tot = 0; lim = (1 << n);
for (int i = 0; i <= n; ++i) hd[i] = 0;
for (int i = 1, u, v, w; i <= m; ++i) {
u = rd() - 1; v = rd() - 1; w = rd();
add(u, v, w); add(v, u, w);
}
memset(f, 0x1f, sizeof(f));
memset(g, 0x1f, sizeof(g));
memset(mn, 0x1f, sizeof(mn));
memset(sec, 0x1f, sizeof(sec));
int inf = f[0];
//处理 mn 和 sec
for (int s = 1; s < lim; ++s)
for (int u = 0; u < n; ++u)
if ((s & (1 << u)) == 0)
for (int i = hd[u], v; i; i = e[i].nxt) {
v = e[i].to;
if ((s & (1 << v)) == 0) continue;
if (e[i].w < mn[u][s]) {
sec[u][s] = mn[u][s];
mn[u][s] = e[i].w; continue;
} else sec[u][s] = min(sec[u][s], e[i].w);
}
//处理 g
for (int u = 0; u < n; ++u) g[u][u][1 << u] = 0;
for (int s = 1; s < lim; ++s)
for (int u = 0; u < n; ++u)
for (int x = 0; x < n; ++x)
if (g[u][x][s] < inf)
for (int i = hd[u], v; i; i = e[i].nxt) {
v = e[i].to;
if (s & (1 << v)) continue;
mmin(g[v][x][s | (1 << v)], g[u][x][s] + e[i].w);
}
//处理 f
for (int u = 0; u < n; ++u) f[1 << u] = 0;
for (int nw = 1; nw < lim; ++nw)
if (countbit(nw) >= 2) {
for (int s = nw & (nw - 1); s; s = (s - 1) & nw) {
int t = nw - s;
for (int u = 0; u < n; ++u)
if (s & (1 << u)) for (int v = 0; v < n; ++v)
if (s & (1 << v) && g[u][v][s] < inf) {
if (u == v) f[nw] = min(f[nw], f[t] + g[u][v][s] + mn[u][t] + sec[u][t]);
else f[nw] = min(f[nw], f[t] + g[u][v][s] + mn[u][t] + mn[v][t]);
}
}
}
if (f[lim - 1] == inf) puts("impossible");
else printf("%d\n", f[lim - 1]);
} int main() {
int testcase = rd();
while (testcase--) work();
return 0;
}

[ SNOI 2013 ] Quare的更多相关文章

  1. 2013 Asia Changsha Regional Contest---Josephina and RPG(DP)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4800 Problem Description A role-playing game (RPG and ...

  2. SharePoint 2013: A feature with ID has already been installed in this farm

    使用Visual Studio 2013创建一个可视web 部件,当右击项目选择"部署"时报错: "Error occurred in deployment step ' ...

  3. Visual Studio 2013 添加一般应用程序(.ashx)文件到SharePoint项目

    默认,在用vs2013开发SharePoint项目时,vs没有提供一般应用程序(.ashx)的项目模板,本文解决此问题. 以管理员身份启动vs2013,创建一个"SharePoint 201 ...

  4. SharePoint 2013 create workflow by SharePoint Designer 2013

    这篇文章主要基于上一篇http://www.cnblogs.com/qindy/p/6242714.html的基础上,create a sample workflow by SharePoint De ...

  5. Install and Configure SharePoint 2013 Workflow

    这篇文章主要briefly introduce the Install and configure SharePoint 2013 Workflow. Microsoft 推出了新的Workflow ...

  6. SharePoint 2013 configure and publish infopth

    This article will simply descript how to configure and publish a InfoPath step by step. Note: To con ...

  7. TFS 2013 培训视频

    最近给某企业培训了完整的 TFS 2013 系列课程,一共四天. 下面是该课程的内容安排: 项目管理     建立项目     成员的维护     Backlog 定义     任务拆分     迭代 ...

  8. Visual Studio 2013 Ultimate因为CodeLens功能导致Microsoft.Alm.Shared.Remoting.RemoteContainer.dll高CPU占用率的折中解决方案

    1.为什么Microsoft.Alm.Shared.Remoting.RemoteContainer.dll的CPU占用率以及内存使用率会那么高? 在Visual Studio 2013 Ultima ...

  9. 沙盒解决方案解决SharePoint 2013 以其他身份登陆的问题

    众所周知,SharePoint 2013没有像SharePoint 2010那样有一个叫"以其他身份登录"的菜单项. 当然解决方案也很多,比如你可以直接修改Welcome.ascx ...

随机推荐

  1. 教你开发jQuery插件

    jQuery插件开发模式 软件开发过程中是需要一定的设计模式来指导开发的,有了模式,我们就能更好地组织我们的代码,并且从这些前人总结出来的模式中学到很多好的实践. 根据<jQuery高级编程&g ...

  2. java如何判断字符串是否为空(小知识)

    方法一: 最多人使用的一个方法, 直观, 方便, 但效率很低: if(s == null ||"".equals(s));方法二: 比较字符串长度, 效率高, 是我知道的最好一个方 ...

  3. android之View坐标系(view获取自身坐标的方法和点击事件中坐标的获取)

    在做一个view背景特效的时候被坐标的各个获取方法搞晕了,几篇抄来抄去的博客也没弄很清楚. 现在把整个总结一下. 其实只要把下面这张图看明白就没问题了. 涉及到的方法一共有下面几个: view获取自身 ...

  4. poj 2253 Frogger 解题报告

    题目链接:http://poj.org/problem?id=2253 题目意思:找出从Freddy's stone  到  Fiona's stone  最短路中的最长路. 很拗口是吧,举个例子.对 ...

  5. 一步一步学Silverlight 2系列文章

    概述 由TerryLee编写的<Silverlight 2完美征程>一书,已经上市,在该系列文章的基础上补充了大量的内容,敬请关注.官方网站:http://www.dotneteye.cn ...

  6. 无限轮播器的bug修复

    前言:上一回实现了轮播器的自动滚动,但是有两个需要处理的bug. 1.增加需求:当用手拖拽控制轮播器的时候,停止自动滚动. 2.当同一个页面中有tableView,textView或scrollvie ...

  7. 【转】[钉钉通知系列]Jenkins发布后自动通知

    转载请注明出处:https://www.cnblogs.com/jianxuanbing/p/7211006.html 阅读目录 一.前言 二.使用钉钉推送的优势 三.配置 一.前言 最近使用Jenk ...

  8. Redis的相关命令

    Redis的相关命令 redis程序的命令 /usr/bin/redis-benchmark /usr/bin/redis-check-aof /usr/bin/redis-check-rdb /us ...

  9. 关于git本地已有项目

    终于要开始彻底掌握git了,第一步自然是自己建个test repository.然而,目前只学到git init, git clone啊.都没说怎么上传本地已有仓库,网上一搜吧,全是坑人的,标题还写的 ...

  10. 洛谷 - P1002 - 过河卒 - 简单dp

    https://www.luogu.org/problemnew/show/P1002 方程很好想,题目也很暴力.感谢题目提示数据会很大. #include<bits/stdc++.h> ...