BZOJ4479 : [Jsoi2013]吃货jyy
若$k\leq 15$,那么可以设$d[i][S]$表示经过了$S$集合的边,现在位于$i$点的最短路。
可以用Dijkstra算法在$O(n^22^k)$时间内求出。
否则若$k>15$,那么最坏情况下,它们会形成一个团,将这$k$条边连上后,图中最多剩下$7$个连通块。
如果知道哪些边要走,哪些边不走的话,那么只要存在欧拉回路就可以。
也就是说,所有点的度数都是偶数,且从$1$出发可以到达$k$条边的端点。
于是考虑DP,设$f[i][j][k]$表示考虑前$i$条边,目前连通性为$j$,每个点度数的奇偶性为$k$的最小代价。
时间复杂度$O(n^2Bell(7)2^n)$,状态比较稀疏,可以通过。
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
typedef pair<int,int>P;
typedef pair<int,P>PI;
typedef long long ll;
const int N=13,M=880,inf=100000000,LIM=15;
int n,m,K,o,i,j,k,x,y,z;
inline void up(int&a,int b){a>b?(a=b):0;}
namespace SMALL{
int f[N][N][2],g[N][N],d[N][1<<LIM];priority_queue<PI,vector<PI>,greater<PI> >q;
inline void ext(int x,int y,int z){
if(d[x][y]<=z)return;
q.push(PI(d[x][y]=z,P(x,y)));
}
void solve(){
for(i=0;i<n;i++)for(j=0;j<n;j++)f[i][j][0]=-1;
for(i=0;i<n;i++)for(j=0;j<n;j++)g[i][j]=inf;
for(i=0;i<K;i++){
scanf("%d%d%d",&x,&y,&z);x--,y--;
f[x][y][0]=f[y][x][0]=i;
f[x][y][1]=f[y][x][1]=z;
}
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&x,&y,&z);x--,y--;
up(g[x][y],z),up(g[y][x],z);
}
for(i=0;i<n;i++)for(j=0;j<1<<K;j++)d[i][j]=inf;
ext(0,0,0);
while(!q.empty()){
PI t=q.top();q.pop();
x=t.second.first,y=t.second.second,z=t.first;
if(z>d[x][y])continue;
for(i=0;i<n;i++){
if(~f[x][i][0])ext(i,y|(1<<f[x][i][0]),z+f[x][i][1]);
ext(i,y,z+g[x][i]);
}
}
printf("%d",d[0][(1<<K)-1]);
}
}
namespace BIG{
bool must[N];
int a[N],h,t,e[N][N],dp[2][1<<N],g[M][N][N],ans=inf;
int w[2][M][1<<N];
char T,v[2][M][1<<N];
short s[2][M][1<<N],cnt[2][M];
ll q[M];
map<ll,int>id;
inline void merge(int x,int y){
x=a[x],y=a[y];
for(int i=0;i<n;i++)if(a[i]==x)a[i]=y;
}
inline ll encode(){
int i,m=0;ll t=0;
static int v[N];
for(i=0;i<n;i++)v[a[i]]=-1;
for(i=0;i<n;i++){
if(v[a[i]]<0)v[a[i]]=m++;
t=t<<4|v[a[i]];
}
return t;
}
inline void decode(ll f){for(int i=n-1;~i;i--)a[i]=f&15,f>>=4;}
inline bool check(ll f){
decode(f);
for(int i=0;i<n;i++)if(must[i]&&a[i]!=a[0])return 0;
return 1;
}
inline int ext(ll x){
int&o=id[x];
if(o)return o;
q[o=++t]=x;
return o;
}
inline void clr(){
T++;
for(int i=1;i<=t;i++)cnt[o^1][i]=0;
}
inline void add(int x,int y,int z){
if(z>=inf)return;
if(v[o^1][x][y]<T){
v[o^1][x][y]=T;
w[o^1][x][y]=z;
s[o^1][x][cnt[o^1][x]++]=y;
return;
}
up(w[o^1][x][y],z);
}
void solve(){
for(i=0;i<n;i++)a[i]=i;
for(i=1;i<1<<n;i++)dp[0][i]=inf;
while(K--){
scanf("%d%d%d",&x,&y,&z);x--,y--;
must[x]=must[y]=1;
merge(x,y);
for(i=0;i<1<<n;i++)dp[o^1][i]=inf;
for(i=0;i<1<<n;i++)if(dp[o][i]<inf){
up(dp[o^1][i^(1<<x)^(1<<y)],dp[o][i]+z);
up(dp[o^1][i],dp[o][i]+z+z);
}
o^=1;
}
decode(encode());
h=1;
ext(encode());
while(h<=t){
ll x=q[h];
for(i=0;i<n;i++)for(j=0;j<n;j++){
decode(x);
merge(i,j);
g[h][i][j]=ext(encode());
}
h++;
}
scanf("%d",&m);
for(i=0;i<n;i++)for(j=0;j<n;j++)e[i][j]=inf;
while(m--){
scanf("%d%d%d",&x,&y,&z);x--,y--;
if(x==y)continue;
if(x>y)swap(x,y);
up(e[x][y],z);
}
clr();
for(i=0;i<1<<n;i++)add(1,i,dp[o][i]);
o^=1;
for(x=0;x<n;x++)for(y=0;y<n;y++)if(e[x][y]<inf){
z=e[x][y];
clr();
for(i=1;i<=t;i++)for(j=0;j<cnt[o][i];j++){
int S=s[o][i][j],f=w[o][i][S];
add(i,S,f);
add(g[i][x][y],S^(1<<x)^(1<<y),f+z);
add(g[i][x][y],S,f+z+z);
}
o^=1;
}
for(i=1;i<=t;i++)if(check(q[i]))for(j=0;j<cnt[o][i];j++)if(!s[o][i][j])up(ans,w[o][i][0]);
printf("%d",ans);
}
}
int main(){
scanf("%d%d",&n,&K);
if(!K)return puts("0"),0;
if(K<=LIM)SMALL::solve();else BIG::solve();
return 0;
}
BZOJ4479 : [Jsoi2013]吃货jyy的更多相关文章
- BZOJ4479 [JSOI2013] 吃货jyy 解题报告(三进制状态压缩+欧拉回路)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4479 Description [故事背景]作为JSOI的著名吃货,JYY的理想之一就是吃 ...
- BZOJ 4479: [Jsoi2013]吃货jyy
一句话题意:求必须包含某K条边的回路(回到1),使得总权值最小 转化为权值最小的联通的偶点 令F[i]表示联通状态为i的最小权值,(3^n状压)表示不在联通块内/奇点/偶点,连边时先不考虑必选的边的度 ...
- P6085-[JSOI2013]吃货JYY【状压dp,欧拉回路】
正题 题目链接:https://www.luogu.com.cn/problem/P6085 题目大意 \(n\)个点的一张无向图,有\(k\)条必走边,\(m\)条其他边,求从\(1\)出发经过必走 ...
- 云计算 IaaS,SaaS,PaaS的区别?一个通俗易懂的吃货文章
来自一篇吃货文章了: ———————————————————— <img src="https://pic2.zhimg.com/a55676f8e1b084a398f8cd5 ...
- 小项目,吃货联盟,java初级小项目,源代码
1:项目的实现效果.功能如图所示. 2:项目的源代码如下: import java.util.Scanner; /** * 吃货联盟订餐管理系统 * */ public class OrderingM ...
- 以吃货的角度去理解云计算中On-Premise、IaaS、PaaS和SaaS
了解云计算的一定都听过四个“高大上”的概念:On-Premise(本地部署),IaaS(基础设施及服务).PaaS(平台即服务)和SaaS(软件即服务),这几个术语并不好理解.不过,如果你是个吃货,还 ...
- java基础10 吃货联盟点餐系统
public class OrderMsg { public static void main(String[] args) throws Exception { /** * 订餐人姓名.选择菜品.送 ...
- 2018年湘潭大学程序设计竞赛 E 吃货
题目描述 作为一个标准的吃货,mostshy又打算去联建商业街觅食了.混迹于商业街已久,mostshy已经知道了商业街的所有美食与其价格,而且他给每种美食都赋予了一个美味度,美味度越高表示他越喜爱这种 ...
- Java 吃货联盟
import java.util.Scanner; public class Shao { private static final int[] dishNames = null; private ...
随机推荐
- Python-数据类型之数字
一:数字类型概述 数字提供了标量存储和直接访问,属于不可变数据类型,所谓不可变,我们可以认为,更改数字的值会生成一个新的对象 # id可以唯一表示一个对象 age =18 print(id(age)) ...
- NodeJs——router报错原因
rout.js var http = require('http'); var url = require('url'); var router = require('./models/router. ...
- K3 WISE 开发插件《SQL语句WHERE查询-范围查询/模糊查询》
0.存储过程开头变量定义 @FBeginDate varchar(10), --单据起始日期 @FEndDate varchar(10), --单据截止日期. @FItemID varchar(50) ...
- github协作开发遇到的问题
1.十一来了,帝都不好买票,30号就调休一天回去了,项目还没搞完,紧张的不行,就自己和同事搞了一个github协作开发,由于是功能和公司项目不是很沾边,但是是自己的主要工作,就和同事协调了一下,搭建了 ...
- 一脸懵逼学习keepalived(对Nginx进行热备)
1:Keepalived的官方网址:http://www.keepalived.org/ 2:Keepalived:可以实现高可靠: 高可靠的概念: HA(High Available), 高可用性集 ...
- 利用 Windows API Code Pack 修改音乐的 ID3 信息
朋友由于抠门 SD 卡买小了,结果音乐太多放不下,又不舍得再买新卡,不得已决定重新转码,把音乐码率压低一点,牺牲点音质来换空间(用某些人的话说,反正不是搞音乐的,听不出差别)… 结果千千静听(百度音乐 ...
- Temporal Segment Networks
摘要 解决问题 用CNN框架有效提取video长时序特征 在UCF101等训练集受限的情况下训练网络 贡献 TSN网络,基于长时间时序结构模型.稀疏时序采样策略,视频层监督有效学习整个视频. HMDB ...
- 转:ubuntu-E:Encountered a section with no Package: header的解决办法
http://blog.csdn.net/hs794502825/article/details/7835902 blog.csdn.net/lixiang0522/article/details/7 ...
- python linux 源码安装Twisted
下载:1.首先找到需要的包访问:https://pypi.org/在搜索框中输入你要查找的包名,然后点击搜索2.选择要下载的包的版本,点击download files3.选择file Type为sou ...
- Flink的广播变量
Flink支持广播变量,就是将数据广播到具体的taskmanager上,数据存储在内存中,这样可以减缓大量的shuffle操作: 比如在数据join阶段,不可避免的就是大量的shuffle操作,我们可 ...