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 ...
随机推荐
- docker日志清理
前言:docker运行久了,会发现它的映射磁盘空间爆满,尤其是yum安装的docker的 解决方法: 1. 用脚本清理,一般yum安装的docker,其存储空间一般都在/var/lib/docker/ ...
- Pthon面向对象之基础
命名空间 class Course: language = 'Chinese' def __init__(self,teacher,name,period,price): self.teacher = ...
- IDEA的字体设置
最后点击ok
- SQLServer 常见高CPU利用率原因
1.缺失索引: USE AdventureWorks2014 SET STATISTICS TIME ON; SET STATISTICS IO ON ; SELECT per.FirstName,p ...
- XShell发送命令到全部会话
- Java-把日期字符串转换成另一种格式的日期字符串
package com.example.demo.utils; import java.text.ParseException; import java.text.SimpleDateFormat; ...
- Java基础知识➣环境搭建与类型整理(一)
概述 公司业务需要,产品既要有.NET又需要Java,没得选择,只能业余时间学习Java,整体觉得Java也.NET还是很相似的,只是语法有差别,差别也不是很大,这就将学习Java的基础知识整理下,以 ...
- Nodejs通过账号密码连接MongoDB数据库
转自https://blog.csdn.net/szu_lzz/article/details/77435804#commentBox 1.创建管理员 首先开启Mongo服务,然后切换admin数据库 ...
- $_FILES["file"]["error"]是错误代码
$_FILES["file"]["error"]是错误代码,0表示没有错误,下面几种对应不同的错误1 : 上传的文件超过了 php.ini 中 upload_m ...
- 【原创】java socket 和.net socket 通讯 demo
结束符协议"##" import java.io.BufferedReader; import java.io.IOException; import java.io.InputS ...