\(\mathcal{Description}\)

  Link.

  给定一个含 \(n\) 个点 \(m\) 条边的简单无向图,每条边的两种定向方法各有权值,求使得图强连通且定向权值和最小的方法。

  \(n\le 18\)。

\(\mathcal{Solution}\)

  涉及到叫做“耳分解”的知识点。

有向图 \(G=(V,E)\) 是否强连通有以下判别方法:

  • 取任意 \(u\in V\),令点集 \(S=\{u\}\);
  • 反复取 \(x,y\in S\),以及连接 \(x,y\) 的一条有向路径 \(P=\lang x,u_1,\cdots,u_k,y\rang\),满足 \(u_i\not\in S,~i\in[1,k]\),并令 \(S\leftarrow S\cup\{u_1,\cdots,u_k\}\)。
  • 若 \(S=V\),则 \(G\) 强连通;否则即找不到增广路 \(P\),\(G\) 非强连通。

其中 \(P\) 就是一个“耳”,这就是“耳分解”。

——当然“耳”貌似最初定义于无向图。

  知道了这个构造强连通图的 trick 就极简了,首先在双向边权中随便选一个预支付代价,并令 \(f(S)\) 表示在 \(S\) 的导出子图内使 \(S\) 强连通的最小代价,\(g(S,x,y,0/1)\) 表示点集 \(S\) 中,当前正在构造的“耳”从 \(x\) 出发,希望回到 \(y\),不能/能 直接走 \(\lang x,y\rang\) 这条边。随便转移即可。复杂度上限是 \(\mathcal O(2^nn^3)\),但算法本身和状态合法性带来了小常数√

\(\mathcal{Code}\)

/*~Rainybunny~*/

#include <cstdio>
#include <cstring> #define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i ) const int MAXN = 18, IINF = 0x3f3f3f3f;
int n, adj[MAXN + 5][MAXN + 5], f[1 << MAXN], g[1 << MAXN][MAXN][MAXN][2]; inline void chkmin( int& a, const int b ) { b < a && ( a = b ); }
inline int imin( const int a, const int b ) { return a < b ? a : b; } int main() {
// freopen( "data.in", "r", stdin ); scanf( "%d", &n );
rep ( i, 0, n - 1 ) rep ( j, 0, n - 1 ) scanf( "%d", &adj[i][j] ); int ans = 0;
rep ( i, 0, n - 1 ) rep ( j, i + 1, n - 1 ) {
if ( ~adj[i][j] ) {
int t = imin( adj[i][j], adj[j][i] );
ans += t, adj[i][j] -= t, adj[j][i] -= t;
}
} memset( f, 0x3f, sizeof f ), memset( g, 0x3f, sizeof g ), f[1] = 0;
rep ( S, 1, ( 1 << n ) - 1 ) if ( S & 1 ) {
rep ( u, 0, n - 1 ) if ( S >> u & 1 ) {
rep ( v, 0, n - 1 ) if ( S >> v & 1 && ~adj[u][v] ) {
chkmin( f[S], g[S][u][v][1] + adj[u][v] );
}
} rep ( u, 0, n - 1 ) if ( S >> u & 1 ) {
rep ( v, 0, n - 1 ) if ( S >> v & 1 ) {
chkmin( g[S][u][v][0], f[S] );
}
} rep ( u, 0, n - 1 ) if ( S >> u & 1 ) {
rep ( v, 0, n - 1 ) if ( S >> v & 1 ) {
int* cur = g[S][u][v];
if ( cur[0] != IINF ) {
rep ( w, 0, n - 1 ) if ( ~adj[u][w] && !( S >> w & 1 ) ) {
chkmin( g[S | 1 << w][w][v][u != v],
cur[0] + adj[u][w] );
}
}
if ( cur[1] != IINF ) {
rep ( w, 0, n - 1 ) if ( ~adj[u][w] && !( S >> w & 1 ) ) {
chkmin( g[S | 1 << w][w][v][1], cur[1] + adj[u][w] );
}
}
}
}
} printf( "%d\n", f[( 1 << n ) - 1] == IINF ? -1 : ans + f[( 1 << n ) - 1] );
return 0;
}

Solution -「Gym 102759C」Economic One-way Roads的更多相关文章

  1. Solution -「Gym 102979E」Expected Distance

    \(\mathcal{Description}\)   Link.   用给定的 \(\{a_{n-1}\},\{c_n\}\) 生成一棵含有 \(n\) 个点的树,其中 \(u\) 连向 \([1, ...

  2. Solution -「Gym 102979L」 Lights On The Road

    \(\mathcal{Description}\)   Link.   给定序列 \(\{w_n\}\),选择 \(i\) 位置的代价为 \(w_i\),要求每个位置要不被选择,要不左右两个位置至少被 ...

  3. Solution -「Gym 102956F」Find the XOR

    \(\mathcal{Description}\)   Link.   给定 \(n\) 个点 \(m\) 条边的连通无向图 \(G\),边有边权.其中 \(u,v\) 的距离 \(d(u,v)\) ...

  4. Solution -「Gym 102956B」Beautiful Sequence Unraveling

    \(\mathcal{Description}\)   Link.   求长度为 \(n\),值域为 \([1,m]\) 的整数序列 \(\lang a_n\rang\) 的个数,满足 \(\not\ ...

  5. Solution -「Gym 102956F」Border Similarity Undertaking

    \(\mathcal{Description}\)   Link.   给定一张 \(n\times m\) 的表格,每个格子上写有一个小写字母.求其中长宽至少为 \(2\),且边界格子上字母相同的矩 ...

  6. Solution -「Gym 102956A」Belarusian State University

    \(\mathcal{Description}\)   Link.   给定两个不超过 \(2^n-1\) 次的多项式 \(A,B\),对于第 \(i\in[0,n)\) 个二进制位,定义任意一个二元 ...

  7. Solution -「Gym 102798I」Sean the Cuber

    \(\mathcal{Description}\)   Link.   给定两个可还原的二阶魔方,求从其中一个状态拧到另一个状态的最小步数.   数据组数 \(T\le2.5\times10^5\). ...

  8. Solution -「Gym 102798K」Tree Tweaking

    \(\mathcal{Description}\)   Link.   给定排列 \(\{p_n\}\),求任意重排 \(p_{l..r}\) 的元素后,将 \(\{p_n\}\) 依次插入二叉搜索树 ...

  9. Solution -「Gym 102798E」So Many Possibilities...

    \(\mathcal{Description}\)   Link.   给定非负整数序列 \(\{a_n\}\) 和 \(m\),每次随机在 \(\{a\}\) 中取一个非零的 \(a_i\)(保证存 ...

随机推荐

  1. Python多线程、线程池及实际运用

    我们在写python爬虫的过程中,对于大量数据的抓取总是希望能获得更高的速度和效率,但由于网络请求的延迟.IO的限制,单线程的运行总是不能让人满意.因此有了多线程.异步协程等技术. 下面介绍一下pyt ...

  2. 记一次ARM服务器(鲲鹏920)的PXE批量装机遇到的坑

    由于近期项目需要,在对一批华为鲲鹏920的ARM服务器(型号为天宫TG225 B1)进行批量装机的过程中,遇到了各种各样千奇百怪的bug(换个高情商的说法就是遇到了各种各样和x86服务器不一样的地方) ...

  3. lua中的三目运算符

    开头先说结论 1.简单版三目运算符(需要自我保证"b"不为"false") a and b or c 2.通用版三目运算符 (a and {b} or {c}) ...

  4. Python科学计算类库

    Numpy是什么 Numpy是一个开源的Python科学计算库.使用Numpy,就可以很自然地使用数组和矩阵.Numpy包含很多实用的数学函数,涵盖线性代数运算.傅里叶变换和随机数生成等功能. 矩阵: ...

  5. 【Java】toString

    toString 当我们输出一个对象的引用时,实际上就是调用当前对象的toString() Object类中toString()的定义: public String toString() { retu ...

  6. 微服务架构 | *3.5 Nacos 服务注册与发现的源码分析

    目录 前言 1. 客户端注册进 Nacos 注册中心(客户端视角) 1.1 Spring Cloud 提供的规范标准 1.2 Nacos 的自动配置类 1.3 监听服务初始化事件 AbstractAu ...

  7. 搭建服务器之DNS

    DNS服务器,实用软件为bind,服务守护进程为named,一下记录一下自己的搭建过程: 1.yum install bind*  其中包括bind本身软件,测试dns的一些工具dig,nslooku ...

  8. Vue.use()用法

    通常我们引入一个第三方组件形式的插件进来时,我们在main.js里面需要Vue.use('该插件名字'),比如引入一个vant组件 那么我们如何自己也来尝试将自己封装的组件以Vue.use()的形式来 ...

  9. Servlet Listener(监听器)

    监听器 Listener 是一个实现特定接口的 Java 程序,这个程序专门用于监听另一个 Java 对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即自动执行.监听器的相关概 ...

  10. JQ的使用

    1.hello,word <script type="text/javascript" src="js/jquery-1.10.1.js">< ...