当前位置:网站首页>【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;
}
边栏推荐
- Desai wisdom number - other charts (parallel coordinate chart): employment of fresh majors in 2021
- map数组函数
- 7_ Openresty installation
- CorelDRAW 2022 Chinese Simplified 64 bit direct download
- @ConfigurationProperties和@Value的区别
- FL Studio20.9水果软件高级中文版电音编曲
- import tensorflow. contrib. Slim as slim error
- 在unity中使用jieba分词的方法
- Map array function
- ANR问题的分析与解决思路
猜你喜欢

The image variables in the Halcon variable window are not displayed, and it is useless to restart the software and the computer

Visual effects, picture to cartoon function

SWT / anr problem - storagemanagerservice stuck

PMP是什么?

详解数据治理知识体系

AI 边缘计算平台 - BeagleBone AI 64 简介

Pulsar geo replication/ disaster recovery / regional replication

Fix names in the table (first character uppercase, other lowercase)

最新微信ipad协议 CODE获取 公众号授权等

js中的图片预加载
随机推荐
小程序自定义顶部导航栏,uni-app微信小程序自定义顶部导航栏
C # generates PPK files in putty format (supports passphrase)
(翻译)实时内联验证更容易让用户犯错的原因
Analysis and solution of anr problems
项目管理是什么?
In the fourth week of June, the list - flying melon data up main growth ranking list (BiliBili platform) was released!
在unity中使用jieba分词的方法
What is project management?
(summary I) Halcon Foundation's target finding features + becoming a regular
The latest CSDN salary increase technology stack in 2022 overview of APP automated testing
十大劵商如何开户?还有,在线开户安全么?
SWT / anr problem - SWT caused by too long dump time
import tensorflow.contrib.slim as slim报错
(总结一)Halcon基础之寻找目标特征+转正
Machine learning 10 belief Bayesian classifier
@The difference between configurationproperties and @value
SWT/ANR问题--Dump时间过长导致的SWT
如何在智汀中實現智能鎖與燈、智能窗簾電機場景聯動?
Ernie-gram, 显式、完备的 n-gram 掩码语言模型,实现了显式的 n-gram 语义单元知识建模。
[punch in questions] integrated daily 5 questions sharing (phase I)