Description

世界上一共有N个JYY愿意去的城市,分别从1编号到N。JYY选出了K个他一定要乘坐的航班。除此之外,还有M个JYY没有特别的偏好,可以乘坐也可以不乘坐的航班。
一个航班我们用一个三元组(x,y,z)来表示,意义是这趟航班连接城市x和y,并且机票费用是z。每个航班都是往返的,所以JYY花费z的钱,既可以选择从x飞往y,也可以选择从y飞往x。
南京的编号是1,现在JYY打算从南京出发,乘坐所有K个航班,并且最后回到南京,请你帮他求出最小的花费。

Input

输入数据的第一行包含两个整数N和K;
接下来K行,每行三个整数x,y,z描述必须乘坐的航班的信息,数据保证在这K个航班中,不会有两个不同的航班在同一对城市之间执飞;
第K+2行包含一个整数M;
接下来M行,每行三个整数x,y,z 描述可以乘坐也可以不乘坐的航班信息。

Output

输出一行一个整数,表示最少的花费。数据保证一定存在满足JYY要求的旅行方案。

Sample Input

6 3
1 2 1000
2 3 1000
4 5 500
2
1 4 300
3 5 300

Sample Output

3100

Data Constraint

对于10%的数据满足N≤4;
对于30%的数据满足N≤ 7;
对于额外30%的数据满足,JYY可以只通过必须乘坐的K个航班从南京出发到达任意一个城市;
对于100%的数据满足2≤N≤13,0≤K≤78,2 ≤M ≤ 200,1 ≤x,y ≤N,1 ≤z ≤ 10^4。

思路

首先根据题意,很明显,我们需要一个欧拉图。

由于数据很小,自然想到状压DP

逐个加点来构成一个连通图,用三进制来状压,0,1,2分别表示不在连通图中,在连通图中且度为奇数,在连通图中且度为偶数。

转移的时候考虑枚举一个不在连通图中的点,然后有两种转移,
1. 该点通过一条必须要走的边与连通图相连,那么贡献为0(事先加上必须经过边的权值)
2. 一种是通过与某个点j的最短路径来与连通图相连,同时这两个点的度数奇偶性都要变化。

由于我们dp初始值都是偶数,所以我们要把度数为奇数的点两两配对。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f,N=15,K=100;
int ss[N],a[N][N],cnt=0,list[N],g[32768],f[4782969],b[N],pow[N],d[N],n,m,tot=0;
struct E
{int to,next,v;
}e[K*2];
void add(int u,int v,int val)
{e[++cnt].to=v; e[cnt].next=list[u]; e[cnt].v=val; list[u]=cnt;
}
void floyd()
{for(int k=1; k<=n; k++)for(int i=1; i<=n; i++)for(int j=1; j<=n; j++)a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
}
void init()
{memset(g,0x3f,sizeof(g));g[0]=0;for(int i=0; i<b[n]; i++)for(int j=1; j<=n; j++) if(!i&(b[j-1]))for(int k=j+1; k<=n; k++) if(!i&(b[k-1]))g[i^b[j-1]^b[k-1]]=min(g[i^b[j-1]^b[k-1]],g[i]+a[j][k]);
}
void dp()
{queue<int> q;memset(f,0x3f,sizeof(f));f[2]=0; q.push(2);while(!q.empty()){int s=q.front(),tot=0; q.pop();for(int i=1; i<=n; i++) if(s/pow[i-1]%3) ss[++tot]=i;for(int i=1; i<=n; i++){if(s/pow[i-1]%3==0){for(int j=list[i]; j; j=e[j].next) if(s/pow[e[j].to-1]%3>0){int s1=s+pow[i-1]*2;if(f[s]>=f[s1]) continue;if(f[s1]==inf) q.push(s1);f[s1]=f[s];}for (int j=1;j<=tot;j++){int s1=s+pow[i-1];s1+=(s/pow[ss[j]-1]%3==1)?pow[ss[j]-1]:-pow[ss[j]-1];if (f[s]+a[i][ss[j]]>=f[s1]) continue;if (f[s1]==inf) q.push(s1);f[s1]=f[s]+a[i][ss[j]];}}}}
}
void solve()
{int ass=inf;for (int s=0; s<pow[n]; s++){int bb=0;for (int i=1; i<=n; i++) if(list[i]&&!(s/pow[i-1]%3>0)) {bb=1; break;}if(bb) continue;int now=s;for(int i=1; i<=n; i++) if(d[i]&1) now+=(s/pow[i-1]%3==1)?pow[i-1]:-pow[i-1];int s1=0;for(int i=1; i<=n; i++) if(now/pow[i-1]%3==1) s1^=b[i-1];ass=min(ass,f[s]+g[s1]);}for(int i=1; i<=cnt; i+=2) ass+=e[i].v;printf("%d",ass);
}
int main()
{scanf("%d%d",&n,&m);memset(a,0x3f,sizeof(a));for(int i=1; i<=m; i++){int x,y,v;scanf("%d%d%d",&x,&y,&v);a[x][y]=a[y][x]=min(a[x][y],v);add(x,y,v); add(y,x,v);d[x]++; d[y]++;}scanf("%d",&m);for(int i=1; i<=m; i++){int x,y,v;scanf("%d%d%d",&x,&y,&v);a[x][y]=a[y][x]=min(a[x][y],v);}b[0]=pow[0]=1;for(int i=1; i<=n; i++) b[i]=b[i-1]*2,pow[i]=pow[i-1]*3;floyd();init();dp();solve();
}

【JZOJ B组】【JSOI2013】吃货JYY相关推荐

  1. bzoj4479: [Jsoi2013]吃货jyy 欧拉回路+状态压缩Dp

    bzoj4479: [Jsoi2013]吃货jyy Description [故事背景] 作为JSOI的著名吃货,JYY的理想之一就是吃遍全世界的美食.要走遍全 世界当然需要不断的坐飞机了.而不同的航 ...

  2. BZOJ4479 [JSOI2013] 吃货jyy 解题报告(三进制状态压缩+欧拉回路)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4479 Description [故事背景] 作为JSOI的著名吃货,JYY的理想之一就是 ...

  3. bzoj 4479: [Jsoi2013]吃货jyy 欧拉回路+状压dp

    题意 世界上一共有N个JYY愿意去的城市,分别从1编号到N.JYY选出了K个他一定要乘坐的航班.除此之外,还有M个JYY没有特别的偏好,可以乘坐也可以不乘坐的航班. 一个航班我们用一个三元组(x,y, ...

  4. [JSOI2013]吃货 JYY

    . . . . . 分析 . . . . . 程序: #include<iostream> #include<cstdio> #include<cstring> # ...

  5. BZOJ 4479: [Jsoi2013]吃货jyy

    一句话题意:求必须包含某K条边的回路(回到1),使得总权值最小 转化为权值最小的联通的偶点 令F[i]表示联通状态为i的最小权值,(3^n状压)表示不在联通块内/奇点/偶点,连边时先不考虑必选的边的度 ...

  6. 【jzoj 3290】【luogu P6085】Foodie / 吃货 JYY(数位DP)(欧拉回路)

    Foodie / 吃货 JYY 题目链接:jzoj 3290 / luogu P6085 题目大意 有 n 个点,有一些路径一定要走,有一些路径可以走可以不走,都有走的费用. 路径双向,然后问你从 1 ...

  7. 吃货JYY[JSOI2013][状压][欧拉回路]

    文章目录 题目 思路 代码 题目 nnn 个点 mmm 条边无向连通图,每条边有权值,指定 KKK 条边必须选,每条边可以经过多次,问从 111 出发遍历完必须边最后回到 111 的最小花费? n≤1 ...

  8. 吃货 JYY / Foodie

    吃货 JYY / Foodie⁡\operatorname{吃货\ JYY\ /\ Foodie}吃货 JYY / Foodie 题目链接:luogu P6085⁡\operatorname{luog ...

  9. 【省选专题一】图论 jzoj 3290【JSOI2013】吃货JYY 状压dp+欧拉回路

    Description 世界上一共有N个JYY愿意去的城市,分别从1编号到N.JYY选出了K个他一定要乘坐的航班.除此之外,还有M个JYY没有特别的偏好,可以乘坐也可以不乘坐的航班. 一个航班我们用一 ...

最新文章

  1. 术语1----边界吸收
  2. 云计算机运行内存,电脑内存,云服务器内存最深刻的解读!
  3. keepalived 主从配置日志报错:one or more vip associated with vrid mismatch actual master advert...
  4. MySQL更新时Error Code:1093和Error Code:1175的解决办法
  5. NLP数据挖掘基础知识
  6. 年轻有为的老黄2020
  7. matlab哈明窗带阻,基于matlabFIR低通,高通,带通,带阻滤波器设计.doc
  8. C语言-获取当前时间-格式化输出(完整代码)
  9. java文件编译后,出现xx$1.class的原因
  10. composer 完整路径才能访问_Docker 漏洞:允许攻击者获得主机 root 访问权限
  11. vue 判断元素内容是否超过宽度
  12. 新巴塞尔资本协议(中英文)
  13. 网络出口究竟选择防火墙,还是路由器?
  14. android 科大讯飞语音播报简单集成
  15. Discuz数据字典1
  16. centos 如何查看操作系统是哪个版本
  17. SecureCRT中文乱码解决(汇总)
  18. 二叉树遍历之前序遍历,中序遍历,后序遍历
  19. mysql首字母大写函数_string - 首字母大写。MySQL的
  20. 【ESP32】【乐鑫发布 AI 语音麦克风阵列开发板 ESP32-Korvo】

热门文章

  1. java 寻找峰值峰谷_Java实现 LeetCode 162 寻找峰值
  2. python使用turtle库、绘制一个八边形_【Python】turtle八边形绘制
  3. Matlab 模拟声波散射,一种目标声散射特征模拟装置的制作方法
  4. H5能取代移动app(Android和iOS)吗?
  5. 微信小程序 实现背景色渐变(css实现)
  6. 操作系统 假脱机(Spooling)系统
  7. HTTP 405 错误 – 方法不被允许 (Method not allowed)【转载】
  8. 永不服输的Java之路---重学Java (第一章)
  9. 阿里大数据平台MaxCompute初窥
  10. 拿蚂蚁头条快手offer怎么选?网友:第一次见头条比快手offer低