题目大意:
  中国邮递员问题。
  给你一个无向带权连通图,求经过所有边并返回起点的最短路径。

思路:
  Edmonds-Johnson算法。
  显然,当原图为欧拉图时,答案即为其欧拉回路的长度。
  考虑原图不存在欧拉回路时的情况。
  一个图存在欧拉回路,当且仅当这个图中度为奇数的点的个数为0。
  然而现在我们的图并不一定是欧拉图,这就说明图中有可能由度数为奇数的点。
  显然,我们需要重复走的边,一定是连接这些度为奇数的点的。
  我们可以用Dijkstra对这些点求最短路(由于数据范围较小,用Floyd也没关系)。
  然后对所有点对之间的最短路构建新图。
  再对新图跑一般图最小权完美匹配(用状压DP或者记忆化搜索)。
  最后匹配出来的匹配就是重复走的路径长度。
  用老图的边权和加上新图的匹配就是答案。
  本来能1A的,但是由于用了平板电视,在POJ上CE了,但是在UVa上就直接0ms0kB过。

 #include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<functional>
#include<ext/pb_ds/priority_queue.hpp>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int inf=0x7fffffff;
const int V=;
struct Edge {
int to,w;
};
std::vector<Edge> e[V];
void add_edge(const int &u,const int &v,const int &w) {
e[u].push_back((Edge){v,w});
e[v].push_back((Edge){u,w});
}
int deg[V];
std::vector<int> kv;
struct Vertex {
int d,id;
bool operator > (const Vertex &another) const {
return d>another.d;
}
};
int n;
int k[V][V];
__gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
__gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[V];
inline void Dijkstra(const int &s) {
int *d=k[s];
q.clear();
for(register int i=;i<=n;i++) {
if(i!=s) {
p[i]=q.push((Vertex){d[i]=inf,i});
} else {
p[i]=q.push((Vertex){d[i]=,i});
}
}
while(q.top().d!=inf) {
const int x=q.top().id;
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to;
if(d[x]+e[x][i].w<d[y]) {
d[y]=d[x]+e[x][i].w;
q.modify(p[y],(Vertex){d[y],y});
}
}
q.modify(p[x],(Vertex){inf,x});
}
}
int f[<<];
inline void init() {
for(register int i=;i<V;i++) {
e[i].clear();
}
kv.clear();
memset(deg,,sizeof deg);
memset(f,-,sizeof f);
}
int dfs(const int st) {
if(!st) return ;
if(~f[st]) return f[st];
f[st]=inf;
for(int i=;i<=n;i++) {
if(!(st&(<<i))) continue;
for(int j=;j<=n;j++) {
if(i==j) continue;
if(!(st&(<<j))) continue;
f[st]=std::min(f[st],dfs(st^(<<i)^(<<j))+k[i][j]);
}
}
return f[st];
}
int main() {
for(;;) {
n=getint();
if(!n) return ;
init();
int m=getint();
int ans=;
for(register int i=;i<m;i++) {
const int &u=getint(),&v=getint(),&w=getint();
deg[u]++,deg[v]++;
add_edge(u,v,w);
ans+=w;
}
int st=;
for(register int i=;i<=n;i++) {
if(deg[i]&) {
kv.push_back(i);
st|=<<i;
}
}
for(register unsigned i=;i<kv.size();i++) {
Dijkstra(kv[i]);
}
ans+=dfs(st);
printf("%d\n",ans);
}
}

[UVa10296]Jogging Trails的更多相关文章

  1. POJ 2404 Jogging Trails

    Jogging Trails Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2122   Accepted: 849 Des ...

  2. [POJ2404]Jogging Trails

    我太弱了. 我们可以知道一个结论就是对于一个图的话假如所有点的度数都是偶数,那么只需要走一波欧拉回路. 所以我们就把奇点补成偶点. 将两个奇点补充到偶点的最佳方法是选择任意两个奇点连最短路径为权的边 ...

  3. [POJ2404]Jogging Trails(中国旅行商问题)(一般图的匹配——状压DP)

    题目:http://poj.org/problem?id=2404 题意:有个n(n<=15)的点和m条无向边,每条边都有自己的权值.现在你要从某个点出发,每条边可以经过多次但要保证每条边至少走 ...

  4. LightOJ1086 Jogging Trails(欧拉回路+中国邮递员问题+SPFA)

    题目求从某点出发回到该点经过所有边至少一次的最短行程. 这个问题我在<图论算法理论.实现及应用>中看过,是一个经典的问题——中国邮递员问题(CPP, chinese postman pro ...

  5. POJ 2404 Jogging Trails [DP 状压 一般图最小权完美匹配]

    传送门 题意:找一个经过所有边权值最小的回路,$n \le 15$ 所有点度数为偶则存在欧拉回路,直接输出权值和 否则考虑度数为奇的点,连着奇数条边,奇点之间走已经走过的路移动再走没走过的路 然后大体 ...

  6. POJ 2404 Jogging Trails(最小权完美匹配)

    [题目链接] http://poj.org/problem?id=2404 [题目大意] 给出一张图,求走遍所有的路径至少一次,并且回到出发点所需要走的最短路程 [题解] 如果图中所有点为偶点,那么一 ...

  7. lightoj 1086 - Jogging Trails(状压dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1086 题解:题目就是求欧拉回路然后怎么判断有欧拉回路只要所有点的度数为偶数.那 ...

  8. HOJ题目分类

    各种杂题,水题,模拟,包括简单数论. 1001 A+B 1002 A+B+C 1009 Fat Cat 1010 The Angle 1011 Unix ls 1012 Decoding Task 1 ...

  9. 【转】POJ百道水题列表

    以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...

随机推荐

  1. solr4.10.3部署到tomcat——(十)

    0. 准备环境:

  2. linux通配符,grep和 egrep区别

    其实主要是正则表达式中的一些特殊语法.在网上找的几篇文章,截取相关部分贴在了下面,方便以后翻阅. 参考:http://hi.baidu.com/sei_zhouyu/item/c18e1a950d2e ...

  3. C# 日文网址转punnycode

    Uri uri = new Uri(url); IdnMapping idn = new IdnMapping();url= url.Replace(uri.Host, idn.GetAscii(ur ...

  4. 高性能.NET MVC之QMVC!

    ASP.NET!这个词代表者一个单词Fat!因为他总是捆绑着太多的太多的类,太多太多的各种功能!你也许会用到,如果你反编译或阅读他们开源的源码,你会不会犹如在大海中找不到方向?不管是Web form ...

  5. Unity教程之-Unity3d中针对Android Apk的签名验证(C#实现)

    当Unity开发的游戏以Android Apk的形式发布之后,经常会遇到的一种情况就是别人对我们的游戏进行二次打包,也就是用他们的签名替换掉我们的签名,从而堂而皇之的将胜利果实占为己有.面对这样的情况 ...

  6. Python基础:内置函数

    本文基于Python 3.6.5的标准库文档编写,罗列了英文文档中介绍的所有内建函数,并对其用法进行了简要介绍. 下图来自Python官网:展示了所有的内置函数,共计68个(14*4+12),大家可以 ...

  7. HTML5 localStorage、sessionStorage 作用域

    一.localStorage localStorage有效期:永不失效,除非web应用主动删除. localStorage作用域:localStorage的作用域是限定在文档源级别的.文档源通过协议. ...

  8. python网络编程-socket发送大数据包问题

    一:什么是socket大数据包发送问题 socket服务器端或者客户端在向对方发送的数据大于对方接受的缓存时,会出现第二次接受还接到上次命令发送的结果.这就出现象第一次接受结果不全,第二次接果出现第一 ...

  9. MyBatis3.4.0以上的分页插件错误:Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named prepare. Cause: java.lang.NoSuchMethodException: org.apache.ibatis.executor.stateme

    错误: Could not find method on interface org.apache.ibatis.executor.statement.StatementHandler named p ...

  10. Java容器---迭代器

    任何容器类,都必须有某种方式可以插入元素并将它们再次取回.毕竟,持有事物是容器最基本的工作. 对于List, add0是插入元素的方法之一,而get()是取出元素的方法之一. 如果从更高层的角度思考, ...