[UVa10296]Jogging Trails
题目大意:
中国邮递员问题。
给你一个无向带权连通图,求经过所有边并返回起点的最短路径。
思路:
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的更多相关文章
- POJ 2404 Jogging Trails
Jogging Trails Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2122 Accepted: 849 Des ...
- [POJ2404]Jogging Trails
我太弱了. 我们可以知道一个结论就是对于一个图的话假如所有点的度数都是偶数,那么只需要走一波欧拉回路. 所以我们就把奇点补成偶点. 将两个奇点补充到偶点的最佳方法是选择任意两个奇点连最短路径为权的边 ...
- [POJ2404]Jogging Trails(中国旅行商问题)(一般图的匹配——状压DP)
题目:http://poj.org/problem?id=2404 题意:有个n(n<=15)的点和m条无向边,每条边都有自己的权值.现在你要从某个点出发,每条边可以经过多次但要保证每条边至少走 ...
- LightOJ1086 Jogging Trails(欧拉回路+中国邮递员问题+SPFA)
题目求从某点出发回到该点经过所有边至少一次的最短行程. 这个问题我在<图论算法理论.实现及应用>中看过,是一个经典的问题——中国邮递员问题(CPP, chinese postman pro ...
- POJ 2404 Jogging Trails [DP 状压 一般图最小权完美匹配]
传送门 题意:找一个经过所有边权值最小的回路,$n \le 15$ 所有点度数为偶则存在欧拉回路,直接输出权值和 否则考虑度数为奇的点,连着奇数条边,奇点之间走已经走过的路移动再走没走过的路 然后大体 ...
- POJ 2404 Jogging Trails(最小权完美匹配)
[题目链接] http://poj.org/problem?id=2404 [题目大意] 给出一张图,求走遍所有的路径至少一次,并且回到出发点所需要走的最短路程 [题解] 如果图中所有点为偶点,那么一 ...
- lightoj 1086 - Jogging Trails(状压dp)
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1086 题解:题目就是求欧拉回路然后怎么判断有欧拉回路只要所有点的度数为偶数.那 ...
- HOJ题目分类
各种杂题,水题,模拟,包括简单数论. 1001 A+B 1002 A+B+C 1009 Fat Cat 1010 The Angle 1011 Unix ls 1012 Decoding Task 1 ...
- 【转】POJ百道水题列表
以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...
随机推荐
- Add Two Numbers I & II
Add Two Numbers I You have two numbers represented by a linked list, where each node contains a sing ...
- 【Linux技术】autotools制作makefile过程详解【转】
转自:http://www.cnblogs.com/lcw/p/3159461.htmlPreface Makefile固然可以帮助make完成它的使命,但要承认的是,编写Makefile确实不是一件 ...
- select()函数用法一
select()函数用法以及FD_ZERO.FD_SET.FD_CLR.FD_ISSET select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用 ...
- jQuery-对标签元素 文本操作-属性操作-文档的操作
一.对标签元素文本操作 1.1 对标签中内容的操作 // js var div1 = document.getElementById("div1"); div1.innerText ...
- linux编译警告 will be initialized after
http://blog.chinaunix.net/uid-17019762-id-3152012.html 作为一个有强迫症的人,实在是受不了 warning 的存在 这个warning是由于初始化 ...
- HTML 多张图片无缝连接
<table border="0" cellspacing="0" cellpadding="0" style="heigh ...
- MySQL字符集编码相关
Windows 10家庭中文版,MySQL 5.7.20,2018-05-07 Part.1 查找数据库的字符集编码 查看MySQL字符集编码:status命令 使用命令行登录MySQL服务器,然后 ...
- Java工程师知识图谱
一.Java工程师知识图谱(思维导图版) 二.Java工程师知识图谱(图文版) 三.Java工程师知识图谱(文字版) http://note.youdao.com/noteshare?id=615da ...
- 2015309南皓芯《Java程序设计》实验一(Java开发环境的熟悉)实验报告
一.实验内容及步骤 (一)使用JDK编译.运行简单的java程序 命令行下的程序开发 步骤一(新建文件夹):打开windows下的cmd → 输入cd Code命令进入Code目录 → 输入md 20 ...
- hdu 4349 求C(n,0),C(n,1),C(n,2)...C(n,n).当中有多少个奇数 (Lucas定理推广)
Lucas定理:把n写成p进制a[n]a[n-1]a[n-2]...a[0],把m写成p进制b[n]b[n-1]b[n-2]...b[0],则C(n,m)与C(a[n],b[n])*C(a[n-1], ...