当前位置:网站首页>【PR #5 A】双向奔赴(状压DP)
【PR #5 A】双向奔赴(状压DP)
2022-07-01 02:24:00 【SSL_TJH】
双向奔赴
题目链接:PR #5 A
题目大意
给你一个简单无向图,然后你要给每条边定向,每个边每个方向有不一样的费用。
然后要你用最小的费用使得这张图强连通,如果无法强连通输出 -1。
思路
首先考虑最暴力的方法,可以直接找一条路径从 1 1 1 出发经过所有点(可以重复经过点),然后回到 1 1 1。
然后我们简化一下题意,我们可以默认选边权小的那个,然后如果要选另一边就要加上差的费用,然后最后加上边权小和。
然后发现我们其实可以把它分割,分割成若干个环。
具体一点就是你已经有一个强连通的子集,然后你每次从一个子集里面的点往外走,一直走没有见过的,然后最后走回到子集里面,然后你外面见到的点也就也跟着强连通了。(这个一直不走见过的是没问题的,因为走见过的你可以把它拆成若干个没有见过的)
然后就有一个大概的状压想法了: g S g_S gS 表示当前 S S S 这个子集强连通的最小费用, f S , i , j f_{S,i,j} fS,i,j 为 S S S 这个子集强连通,环的终点是 i i i,现在在 j j j。
(然后为了我们能表示出走出环的点,所以 f S , i , j f_{S,i,j} fS,i,j 的 S S S 就表示成强连通的子集与现在要加上的点的并集)
然后就是三种,一个是从 g g g 到 f f f,接着是 f f f 内部转移,最后 f f f 到 g g g。
复杂度为 O ( n 3 2 n ) O(n^32^n) O(n32n) 能过。
然后你会发现锅了,因为你这样是不能保证一条边只会从一个方向走的。
(就比如你从 g g g 走一个点到 f f f 结果你直接从 f f f 走回 g g g 了)
那我们考虑怎么办,因为这个时候复杂度已经是很大的了不能再乘 n n n,考虑压缩一下,会发现你 f S , i , j f_{S,i,j} fS,i,j 的 j j j 是一定在 S S S 中的,那我们能不能不在呢?
自然是可以的,那如果我们用不在的方式转移,但是一开始又在呢?
你会发现就不能直接归到答案里面(因为你答案枚举 j j j 是要不在 S S S 里面的),而是要通过走一步消除掉这个特异性(因为你无论怎样都是正常转移,那下一个点肯定不在点集里面),所以就可以走回去了。
然后就可以用这个很妙的方法特判掉这个情况啦!
(具体实现可以看代码)
代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N = 18;
int n, a[N][N], f[1 << N][N][N], g[1 << N], ans;
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &a[i][j]);
for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++)
if (a[i][j] != -1) {
int x = min(a[i][j], a[j][i]);
a[i][j] -= x; a[j][i] -= x; ans += x;
}
memset(f, 0x7f, sizeof(f));
memset(g, 0x7f, sizeof(g)); int inf = g[0];
g[1] = 0;
for (int S = 1; S < (1 << n); S++) {
if (g[S] < inf) {
for (int i = 0; i < n; i++) if ((S >> i) & 1)
for (int s = 0; s < n; s++) if ((S >> s) & 1)
for (int j = 0; j < n; j++) if (!((S >> j) & 1) && a[s][j] != -1) {
if (s != i) f[S][i][j] = min(f[S][i][j], g[S] + a[s][j]);
else f[S | (1 << j)][i][j] = min(f[S | (1 << j)][i][j], g[S] + a[s][j]);//不能从起点出发到这个点就直接到终点
}
}
for (int i = 0; i < n; i++) if ((S >> i) & 1)
for (int j = 0; j < n; j++) if (f[S][i][j] < inf)
for (int k = 0; k < n; k++) if (!((S >> k) & 1) && a[j][k] != -1)
f[S | (1 << j)][i][k] = min(f[S | (1 << j)][i][k], f[S][i][j] + a[j][k]);
for (int i = 0; i < n; i++) if ((S >> i) & 1)
for (int j = 0; j < n; j++) if (!((S >> j) & 1) && f[S][i][j] < inf && a[j][i] != -1)
g[S | (1 << j)] = min(g[S | (1 << j)], f[S][i][j] + a[j][i]);
}
if (g[(1 << n) - 1] < inf) ans += g[(1 << n) - 1];
else ans = -1;
printf("%d", ans);
return 0;
}
边栏推荐
猜你喜欢
![Pytoch -- foundation refers to the north_ II. What high school students can understand [back propagation and gradient descent]](/img/6e/279dbb7a8d7a5ecd240de464c5b8b2.png)
Pytoch -- foundation refers to the north_ II. What high school students can understand [back propagation and gradient descent]

VirtualBox installation enhancements

详解数据治理知识体系

How to realize the scene linkage of intelligent lock, lamp and intelligent curtain motor in zhiting?

UE4渲染管线学习笔记

Delete duplicate email

(summary I) Halcon Foundation's target finding features + becoming a regular

Desai wisdom number - other charts (parallel coordinate chart): employment of fresh majors in 2021

机器学习10-信念贝叶斯分类器

js中的图片预加载
随机推荐
LabVIEW计算相机图像传感器分辨率以及镜头焦距
我的PMP学习考试心得
Machine learning 10 belief Bayesian classifier
SWT / anr problem - binder stuck
CorelDRAW 2022 Chinese Simplified 64 bit direct download
How to realize the scene linkage of intelligent lock, lamp and intelligent curtain motor in zhiting?
开源基础软件公司,寻找一起创造未来的你(API7.ai)
Objects and object variables
With one-stop insight into industry hot spots, the new function "traffic market" of feigua data station B is launched!
Short message sending solution in medical his industry
Focusing on green and low carbon, data center cooling has entered a new era of "intelligent cooling"
[proteus simulation] Arduino UNO +74c922 keyboard decoding drive 4x4 matrix keyboard
How to learn and read code
机器学习9-通用逼近器径向基函数神经网络,在新观点下审视PDA和SVM
The image variables in the Halcon variable window are not displayed, and it is useless to restart the software and the computer
PMP是什麼?
SWT/ANR问题--Dump时间过长导致的SWT
go: finding module for package
SWT / anr problem - SWT caused by too long dump time
详解数据治理知识体系