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。

Hint

样例说明:一个可行的最佳方案为123541。 机票所需的费用为1000+1000+300+500+300=3100。

分析:我们发现一条可行的道路当且仅当经过所有必须经过的边,且此时所有点的入度都为偶数。
我们发现可以dp(一开始都没往这么方向想,不是说图论专题吗= =)。设f[u]为状态为u时的答案,u为一个n位三进制数,第i位0表示点i入度为0,1表示入度为奇数,2表示偶数(把0单独出来是应该该点不在欧拉回路内)。首先把1号点加入连通块内,每次枚举下一个入度为0点的加入这个连通块,再枚举连通块内一个点,把这两个点连起来,显然代价为两点之间的最短路;如果这两点间有直接相连的必须走的边,代价可以看做0,最后再把k条边的代价加上,然后连接的两个点的奇偶性改变,过程中的点奇偶性不改变。
考虑这样一种情况,(u,v)有条代价为x的必走边,还有代价为y的可走边,此时如果x>y,显然是不能把必走边看为0的,只有在这两点间有直接相连的必须走的边(注意这个),代价才算0。我们这样跑出了f[u],它描述的欧拉图在同状态下是一样的,且会把所有必走边跑掉(只要该状态合法)。剩下的就是把1变成2即可。暴力两个1,把这两点连起来,代价为两点最短路,此时必走边不看做0,为初始代价。

代码(by 66w):

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#define MIN(x,y) x=min(x,y)
#define inf 0x3f3f3f3f
using namespace std;const int N=15;int n,m,dis[N][N],cnt,last[N],g[9005],f[1600005],bin[N],pow[N],a[N],deg[N];
struct edge{int to,next,w;}e[N*10];
queue<int> que;int read()
{int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}void addedge(int u,int v,int w)
{e[++cnt].to=v;e[cnt].w=w;e[cnt].next=last[u];last[u]=cnt;e[++cnt].to=u;e[cnt].w=w;e[cnt].next=last[v];last[v]=cnt;
}void floyd()
{for (int k=1;k<=n;k++)for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)MIN(dis[i][j],dis[i][k]+dis[k][j]);
}void pre_dp()
{memset(g,inf,sizeof(g));g[0]=0;for (int i=0;i<bin[n];i++)for (int j=1;j<=n;j++)if (!(i&bin[j-1]))for (int k=j+1;k<=n;k++)if (!(i&bin[k-1]))MIN(g[i^bin[j-1]^bin[k-1]],g[i]+dis[j][k]);
}void dp()
{memset(f,inf,sizeof(f));f[2]=0;que.push(2);while (!que.empty()){int s=que.front(),tot=0;que.pop();for (int i=1;i<=n;i++) if (s/pow[i-1]%3>0) a[++tot]=i;for (int i=1;i<=n;i++)if (s/pow[i-1]%3==0){for (int j=last[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) que.push(s1);f[s1]=f[s];}for (int j=1;j<=tot;j++){int s1=s+pow[i-1];s1+=(s/pow[a[j]-1]%3==1)?pow[a[j]-1]:-pow[a[j]-1];if (f[s]+dis[i][a[j]]>=f[s1]) continue;if (f[s1]==inf) que.push(s1);f[s1]=f[s]+dis[i][a[j]];}}}
}void calc()
{int ans=inf;for (int s=0;s<pow[n];s++){int flag=0;for (int i=1;i<=n;i++) if (last[i]&&!(s/pow[i-1]%3)) {flag=1;break;}if (flag) continue;int now=s;for (int i=1;i<=n;i++) if (deg[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^=bin[i-1];MIN(ans,f[s]+g[s1]);}for (int i=1;i<=cnt;i+=2) ans+=e[i].w;printf("%d",ans);
}int main()
{n=read();m=read();bin[0]=pow[0]=1;for (int i=1;i<=n;i++) bin[i]=bin[i-1]*2,pow[i]=pow[i-1]*3;memset(dis,inf,sizeof(dis));for (int i=1;i<=m;i++){int x=read(),y=read(),z=read();dis[x][y]=dis[y][x]=min(dis[y][x],z);deg[x]++;deg[y]++;addedge(x,y,z);}m=read();while (m--){int x=read(),y=read(),z=read();dis[x][y]=dis[y][x]=min(dis[y][x],z);}floyd();pre_dp();dp();calc();return 0;
}

【省选专题一】图论 jzoj 3290【JSOI2013】吃货JYY 状压dp+欧拉回路相关推荐

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

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

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

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

  3. BZOJ 4479: [Jsoi2013]吃货jyy

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

  4. P7519-[省选联考 2021 A/B 卷]滚榜【状压dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P7519 题目大意 nnn个队伍,队伍之间按照得分从小到大排名,得分相同的按照编号从小到大排.开始时每个队伍有个初始 ...

  5. [JSOI2013]吃货 JYY

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

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

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

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

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

  8. 【状压DP】最优配对问题(jzoj 3420)

    最优配对问题 jzoj 3420 题目大意: 在平面上有n个点,现在要把他们拼成n/2对,拼接两个点的代价是他们的平面距离,现在问代价总和最小是多少 输入样例 4 8730 9323 -3374 39 ...

  9. BZOJ 2734 [HNOI2012]集合选数 (状压DP、时间复杂度分析)

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2734 题解 嗯早就想写的题,昨天因为某些不可告人的原因(大雾)把这题写了,今天再来写题解 ...

最新文章

  1. Matlab实用程序--图形应用-交互式图形
  2. [面向对象] ABAP中程序类如何转化成全局类
  3. 本地区间管理 oracle,Oracle:本地表空间管理,字典表空间管理
  4. .Net在线编辑工具.NET Fiddle
  5. 菜鸟学SQLServer--恢复模式
  6. ?php if ($modules) { ?,phpStudy安装鲶鱼CMS怎样开启伪静态
  7. archLinux 安装拼音输入法
  8. java ee 设计模式_Java EE 设计模式解析与应用_源雷技术空间
  9. AppFuse 2.1的安装运行步骤------利用Maven构建appfuse
  10. DGL笔记1——用DGL表示图
  11. spring AspectJ的Execution表达式expression
  12. 如何用idea比对代码差异
  13. 化妆品电商供应链系统解决方案:美妆化妆品品牌供应链质量管理、产品定位
  14. app live photo_iphone live photo app恢复
  15. 获取Windows 10上文件资源管理器的帮助
  16. CDN加速可以为网络用户解决哪些难题?
  17. 小白科研笔记:简析图神经网络收敛性的理论证明
  18. 【2017秋季校园招聘笔经面经专题汇总】
  19. WebUploader重复多次上传问题
  20. 2022年数维杯国际赛C题翻译

热门文章

  1. 利用单分子技术进行生物研究--光镊在生命科学中的应用
  2. 精准营销,我们这样做
  3. 【7055】《信息简史》读书笔记
  4. tp框架实现点赞功能
  5. rcar-du display timing generation
  6. 如何将图片转换成pdf实用方法
  7. Golang基于学习总结
  8. Xcode7中你一定要知道的炸裂调试神技【转载】
  9. 【浅谈】数学与生活(一)
  10. 微软ERP Microsoft Dynamics AX学习