/*
状压dp
邮递员问题:求经过任意点出发经过每一条边一次并回到原点。
解法:1、如果是欧拉回路那么就是所有的边的总和。
2、一般的解法,找出所有的奇度顶点,任意两个顶点匹配,即最小完美匹配,可用状压dp。
*/
#include<stdio.h>
#include<string.h>
#define N 20
#define inf 1000000000
int ma[N][N];
int lower[N];
int dp[1<<16];//注意这里数组要开够
void floyd(int n) {
int i,j,k;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) {
if(ma[i][k]>=inf||ma[k][j]>=inf)continue;
if(ma[i][j]>ma[i][k]+ma[k][j])
ma[i][j]=ma[i][k]+ma[k][j];
}
return ;
}
int vis[N];
int judge(int n) {
int k=0,num=0;
while(n) {
vis[k]=n%2;
if(vis[k])
num++;
n/=2;
k++;
}
return num;
}
int main() {
int n,m,i,j,k,sum,degree[N],f,to[N],low,last;
lower[0]=1;
for(i=1;i<=17;i++)//二进制
lower[i]=lower[i-1]*2;
while(scanf("%d",&n),n) {
scanf("%d",&m);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
ma[i][j]=(i==j)?0:inf;
memset(degree,0,sizeof(degree));
sum=0;
while(m--) {
scanf("%d%d%d",&i,&j,&k);
if(ma[i][j]>k)
ma[i][j]=ma[j][i]=k;
degree[i]++;//求解度数
degree[j]++;
sum+=k;
}
f=0;
for(i=1;i<=n;i++)
if(degree[i]%2==1)
to[f++]=i;
if(f==0) {//判断是否是欧拉回路
printf("%d\n",sum);
continue;
}
floyd(n);//求解任意两点的距离实际用的只有奇度顶点
// printf("z\n");
low=1<<f;
for(i=1;i<low;i++)//初始化
dp[i]=inf;
dp[0]=0;
//printf("%d\n",f);
for(i=1;i<low;i++) {
memset(vis,0,sizeof(vis));
if(judge(i)%2==1)continue;//如果是奇数不符合
for(j=0;j<f;j++)
for(k=0;k<f;k++) {
if(j==k)continue;//不能相同
if(!vis[j]||!vis[k])continue;//只要有一个没有就不符合
last=i^lower[j]^lower[k];
if(dp[i]>dp[last]+ma[to[j]][to[k]])//当前的状态=去掉j和k的状态+j和k的最短路
dp[i]=dp[last]+ma[to[j]][to[k]];
}
}
// printf("%d\n",dp[low-1]);
printf("%d\n",sum+dp[low-1]);//奇度顶点的总的最小匹配为重复边+总的边数
}
return 0;
}

poj 2404 中国邮递员问题 欧拉回路判定+状压dp的更多相关文章

  1. POJ 3311 Hie with the Pie (状压DP)

    dp[i][j][k] i代表此层用的状态序号 j上一层用的状态序号 k是层数&1(滚动数组) 标准流程 先预处理出所有合法数据存在status里 然后独立处理第一层 然后根据前一层的max推 ...

  2. POJ 1321 棋盘问题(DFS & 状压DP)

    用DFS写当然很简单了,8!的复杂度,16MS搞定. 在Discuss里看到有同学用状态压缩DP来写,就学习了一下,果然很精妙呀. 状态转移分两种,当前行不加棋子,和加棋子.dp[i][j]中,i代表 ...

  3. POJ:1185-炮兵阵地(状压dp入门)

    炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组 ...

  4. 【POJ】1185 炮兵阵地(状压dp)

    题目 传送门:QWQ 分析 看到$ M<=10 $考虑状压. 然后把每行都压一下,那么每个状态相关的就是上一行和上上行的状态. 然后枚举. 然后复杂度最坏是$ O(100 \times 1024 ...

  5. POJ 2411 Mondriaan's Dream 【状压Dp】 By cellur925

    题目传送门 这道题暑假做的时候太模糊了,以前的那篇题解大家就别看了==.今天再复习状压感觉自己当时在写些什么鸭.... 题目大意:给你一个\(n\)*\(m\)的棋盘和许多\(1*2\)的骨牌,骨牌可 ...

  6. POJ 2411 Mondriaan's Dream/[二进制状压DP]

    题目链接[http://poj.org/problem?id=2411] 题意:给出一个h*w的矩形1<=h,w<=11.用1*2和2*1的小矩形去填满这个h*w的矩形,问有多少种方法? ...

  7. POJ 2288 Islands and Bridges(状压dp)

    http://poj.org/problem?id=2288 题意: 有n个岛屿,每个岛屿有一个权值V,一条哈密顿路径C1,C2,...Cn的值为3部分之和: 第1部分,将路径中每个岛屿的权值累加起来 ...

  8. POJ 2441 Arrange the Bulls(状压DP)

    [题目链接] http://poj.org/problem?id=2441 [题目大意] 每个人有过个喜欢的篮球场地,但是一个场地只能给一个人, 问所有人都有自己喜欢的场地的方案数. [题解] 状态S ...

  9. POJ 2686 Traveling by Stagecoach(状压DP)

    [题目链接] http://poj.org/problem?id=2686 [题目大意] 给出一张无向图,你有n张马车票每张车票可以租用ti匹马, 用一张马车票从一个城市到另一个城市所用的时间为这两个 ...

随机推荐

  1. SQL 事务篇和约束

    数据库事务: 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行 事务是恢复和并发控制的基本单位.事务应该具有4个属性 ...

  2. 【知识总结】多项式全家桶(三)(任意模数NTT)

    经过两个月的咕咕,"多项式全家桶" 系列终于迎来了第三期--(雾) 上一篇:[知识总结]多项式全家桶(二)(ln和exp) 先膜拜(伏地膜)大恐龙的博客:任意模数 NTT (在页面 ...

  3. hdu 4104 Discount

    http://acm.hdu.edu.cn/showproblem.php?pid=4104 一开始还以为这题是背包,然后优化下这个背包,但是一直都优化不出来. 然后题解是直接模拟而已,唉 先从小到大 ...

  4. SQLiteDeveloper 工具

    破解方法: cmd下执行命令:  reg delete HKEY_CURRENT_USER\SharpPlus\SqliteDev /f

  5. ES6 学习笔记 - let和const

    let 和 const 命令 学习资料:ECMAScript 6 入门 let 所声明的变量,只在let命令所在的代码块内有效.用途:循环计数器. 如果使用var,只有一个全局变量i: var a = ...

  6. MVC之参数验证(一)

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其数据的准确性.总地来说,我们可以采用Syste ...

  7. mysql的简单优化【简单易学】

    1.选取最适用的字段属性: 表字段尽量设小,不要给数据库增加没必要的空间:如:值为'01'.'02',给char(2)即可: 2.使用连接(JOIN)来代替子查询(Sub-Queries): 使用jo ...

  8. [ USACO 2007 FEB ] Lilypad Pond (Gold)

    \(\\\) \(Description\) 一张\(N\times M\)的网格,已知起点和终点,其中有一些地方是落脚点,有一些地方是空地,还有一些地方是坏点. 现在要从起点到终点,每次移动走日字\ ...

  9. 面试中的一些小问题之html5和html4的区别?

    HTML5建立的一些新规则: 新特性应该基于HTML.CSS.DOM.JavaScript: 减少对外部插件的需求,如flash将会用video标签和audio标签代替: 更加优秀的错误处理: 更多取 ...

  10. 可滚动的ResultSet类型 实现分页

    可滚动的ResultSet类型. 这个类型支持前后滚动取得纪录next().previous(),回到第一行first(),同时还支持要取的 ResultSet中的第几行 absolute(int n ...