﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-I believe-随笔分类-图论*矩阵</title><link>http://www.cppblog.com/luyulaile/category/11037.html</link><description>I  can</description><language>zh-cn</language><lastBuildDate>Sun, 17 Jun 2012 01:43:35 GMT</lastBuildDate><pubDate>Sun, 17 Jun 2012 01:43:35 GMT</pubDate><ttl>60</ttl><item><title>Dijkstra(迪杰斯特拉)算法</title><link>http://www.cppblog.com/luyulaile/archive/2012/06/16/179006.html</link><dc:creator>luis</dc:creator><author>luis</author><pubDate>Fri, 15 Jun 2012 19:53:00 GMT</pubDate><guid>http://www.cppblog.com/luyulaile/archive/2012/06/16/179006.html</guid><wfw:comment>http://www.cppblog.com/luyulaile/comments/179006.html</wfw:comment><comments>http://www.cppblog.com/luyulaile/archive/2012/06/16/179006.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luyulaile/comments/commentRss/179006.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luyulaile/services/trackbacks/179006.html</trackback:ping><description><![CDATA[<span style="font-family: arial, 宋体, sans-serif; font-size: 14px; line-height: 24px; background-color: #ffffff; ">　Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法，用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展，直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法，在很多专业课程中都作为基本内容有详细的介绍，如数据结构，图论，运筹学等等。Dijkstra一般的表述通常有两种方式，一种用永久和临时标号方式，一种是用OPEN, CLOSE表的方式，这里均采用永久和临时标号的方式。注意该算法要求图中不存在负权边。</span><h3><a name="1_2" style="text-decoration: underline; color: rgb(19, 110, 194); "></a><a name="sub1712262_1_2" style="text-decoration: underline; color: rgb(19, 110, 194); "></a>问题描述</h3><span style="font-family: arial, 宋体, sans-serif; font-size: 14px; line-height: 24px; background-color: #ffffff; ">　　在无向图 G=(V,E) 中，假设每条边 E[i] 的长度为 w[i]，找到由顶点 V0 到其余各点的最短路径。（</span><a target="_blank" href="http://baike.baidu.com/view/1939816.htm" style="text-decoration: underline; color: #136ec2; font-family: arial, 宋体, sans-serif; font-size: 14px; line-height: 24px; background-color: #ffffff; ">单源最短路径</a><span style="font-family: arial, 宋体, sans-serif; font-size: 14px; line-height: 24px; background-color: #ffffff; ">）</span>&nbsp;<br /><br /><br /><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; "><em><a target="_blank" href="http://baike.baidu.com/view/358075.htm" style="text-decoration: underline; color: #136ec2; ">迪杰斯特拉</a>(Dijkstra)算法思想</em><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; "></div>　　</strong><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">按路径长度递增次序产生最短路径算法：</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　把V分成两组：</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　（1）S：已求出最短路径的顶点的集合</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　（2）V-S=T：尚未确定最短路径的顶点集合</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　将T中顶点按最短路径递增的次序加入到S中，</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　保证：（1）从源点V0到S中各顶点的最短路径长度都不大于</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　从V0到T中任何顶点的最短路径长度</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　（2）每个顶点对应一个距离值</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　S中顶点：从V0到此顶点的最短路径长度</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　T中顶点：从V0到此顶点的只包括S中顶点作中间</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　顶点的最短路径长度</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　依据：可以证明V0到T中顶点Vk的最短路径，或是从V0到Vk的</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　直接路径的权值；或是从V0经S中顶点到Vk的路径权值之和</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　（反证法可证）</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; "><em>求最短路径步骤</em></strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　算法步骤如下：</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　1. 初使时令 S={V0},T={其余顶点}，T中顶点对应的距离值</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　若存在&lt;V0,Vi&gt;，d(V0,Vi)为&lt;V0,Vi&gt;弧上的权值</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　若不存在&lt;V0,Vi&gt;，d(V0,Vi)为&#8733;</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　2. 从T中选取一个其距离值为最小的顶点W且不在S中，加入S</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　3. 对T中顶点的距离值进行修改：若加进W作中间顶点，从V0到Vi的</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　距离值比不加W的路径要短，则修改此距离值</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　重复上述步骤2、3，直到S中包含所有顶点，即S=T为止</span>&nbsp;<br /><br />代码： 源地址：<span style="color: #008000; font-size: 13px; background-color: #eeeeee; ">www.cnblogs.com/newwy</span>&nbsp;<br /><br /><div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">/*</span><span style="color: #008000; ">********************************<br />*&nbsp;&nbsp;&nbsp;最短路径---Dijkstra算法实现&nbsp;<br />*&nbsp;&nbsp;&nbsp;　　　HDU：2544&nbsp;<br />*&nbsp;&nbsp;&nbsp;BLOG:www.cnblogs.com/newwy<br />*&nbsp;&nbsp;&nbsp;AUTHOR:Wang&nbsp;Yong<br />*********************************</span><span style="color: #008000; ">*/</span><br />#include&nbsp;&lt;iostream&gt;<br /><span style="color: #0000FF; ">#define</span>&nbsp;MAX&nbsp;100<br /><span style="color: #0000FF; ">#define</span>&nbsp;INF&nbsp;1000000000<br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br />&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;dijkstra&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;mat[][MAX],<span style="color: #0000FF; ">int</span>&nbsp;n,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;s,<span style="color: #0000FF; ">int</span>&nbsp;f)<br />&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;dis[MAX];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;mark[MAX];<span style="color: #008000; ">//</span><span style="color: #008000; ">记录被选中的结点&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i,j,k&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i&nbsp;=&nbsp;0&nbsp;;&nbsp;i&nbsp;&lt;&nbsp;n&nbsp;;&nbsp;i++)<span style="color: #008000; ">//</span><span style="color: #008000; ">初始化所有结点，每个结点都没有被选中&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mark[i]&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i&nbsp;=&nbsp;0&nbsp;;&nbsp;i&nbsp;&lt;&nbsp;n&nbsp;;&nbsp;i++)<span style="color: #008000; ">//</span><span style="color: #008000; ">将每个结点到start结点weight记录为当前distance&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dis[i]&nbsp;=&nbsp;mat[s][i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">path[i]&nbsp;=&nbsp;s;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;mark[s]&nbsp;=&nbsp;1;<span style="color: #008000; ">//</span><span style="color: #008000; ">start结点被选中&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">path[s]&nbsp;=&nbsp;0;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;dis[s]&nbsp;=&nbsp;0;<span style="color: #008000; ">//</span><span style="color: #008000; ">将start结点的的距离设置为0&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;min&nbsp;;<span style="color: #008000; ">//</span><span style="color: #008000; ">设置最短的距离。&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i&nbsp;=&nbsp;1&nbsp;;&nbsp;i&nbsp;&lt;&nbsp;n;&nbsp;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min&nbsp;=&nbsp;INF;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(j&nbsp;=&nbsp;0&nbsp;;&nbsp;j&nbsp;&lt;&nbsp;n;j++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(mark[j]&nbsp;==&nbsp;0&nbsp;&nbsp;&amp;&amp;&nbsp;dis[j]&nbsp;&lt;&nbsp;min)<span style="color: #008000; ">//</span><span style="color: #008000; ">未被选中的结点中，距离最短的被选中&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min&nbsp;=&nbsp;dis[j]&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;k&nbsp;=&nbsp;j;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mark[k]&nbsp;=&nbsp;1;<span style="color: #008000; ">//</span><span style="color: #008000; ">标记为被选中&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(j&nbsp;=&nbsp;0&nbsp;;&nbsp;j&nbsp;&lt;&nbsp;n&nbsp;;&nbsp;j++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(&nbsp;mark[j]&nbsp;==&nbsp;0&nbsp;&nbsp;&amp;&amp;&nbsp;(dis[j]&nbsp;&gt;&nbsp;(dis[k]&nbsp;+&nbsp;mat[k][j])))<span style="color: #008000; ">//</span><span style="color: #008000; ">修改剩余结点的最短距离&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dis[j]&nbsp;=&nbsp;dis[k]&nbsp;+&nbsp;mat[k][j];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;dis[f];&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;}&nbsp;<br />&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;mat[MAX][MAX];<br /><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;n,m;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>(scanf("%d&nbsp;%d",&amp;n,&amp;m))<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;a,b,dis;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(n&nbsp;==&nbsp;0&nbsp;||&nbsp;m&nbsp;==&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i,j;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i&nbsp;=&nbsp;0&nbsp;;&nbsp;i&nbsp;&lt;&nbsp;n;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(j&nbsp;=&nbsp;0&nbsp;;&nbsp;j&nbsp;&lt;&nbsp;n;&nbsp;j++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat[i][j]&nbsp;=&nbsp;INF;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(i&nbsp;=&nbsp;0&nbsp;;&nbsp;i&nbsp;&lt;&nbsp;m&nbsp;;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scanf("%d&nbsp;%d&nbsp;%d",&amp;a,&amp;b,&amp;dis);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--a,--b;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(dis&nbsp;&lt;&nbsp;mat[a][b]&nbsp;||&nbsp;dis&nbsp;&lt;&nbsp;mat[b][a])<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat[a][b]&nbsp;=&nbsp;mat[b][a]&nbsp;=&nbsp;dis;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;ans&nbsp;=&nbsp;dijkstra(mat,n,0,n-1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n",ans);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;<br />}</div><br />可用 优先队列优化<br /><br /><br />其他解释：<br /><a href="http://blog.csdn.net/jiahui524/article/details/6636913">http://blog.csdn.net/jiahui524/article/details/6636913</a>&nbsp;<img src ="http://www.cppblog.com/luyulaile/aggbug/179006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luyulaile/" target="_blank">luis</a> 2012-06-16 03:53 <a href="http://www.cppblog.com/luyulaile/archive/2012/06/16/179006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>dijkstra算法 最小堆优化 &lt;不用stl&gt;转帖</title><link>http://www.cppblog.com/luyulaile/archive/2009/08/09/92739.html</link><dc:creator>luis</dc:creator><author>luis</author><pubDate>Sun, 09 Aug 2009 13:28:00 GMT</pubDate><guid>http://www.cppblog.com/luyulaile/archive/2009/08/09/92739.html</guid><wfw:comment>http://www.cppblog.com/luyulaile/comments/92739.html</wfw:comment><comments>http://www.cppblog.com/luyulaile/archive/2009/08/09/92739.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luyulaile/comments/commentRss/92739.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luyulaile/services/trackbacks/92739.html</trackback:ping><description><![CDATA[以后慢慢看<br>------------<br>模板是HDOJ 2544<br>我写的是记录每个点在堆中的位置IncreaseKey，也可以Relax后直接往里插，用个bool数组记录一下<br><br>-----<br>优化之处在于时间复杂度由n^2变为nlgn<br>-----<br>#include&lt;cstdio&gt;<br>#include&lt;cstdlib&gt;<br><br>int n,m;<br>int map[101][101],d[101];<br><br>class Heap<br>{<br>&nbsp;&nbsp;&nbsp; public:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int handle[101];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void Build(int n)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=1;i&lt;=n;i++) a[i]=handle[i]=i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size=n;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void Percup(int p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int temp=a[p];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(;d[temp]&lt;d[a[p&gt;&gt;1]];p&gt;&gt;=1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a[p]=a[p&gt;&gt;1];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handle[a[p]]=p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a[p]=temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handle[a[p]]=p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int DeleteMin()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int val=a[1];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a[1]=a[size--];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Percdown(1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handle[val]=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return val;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool Empty() {return size==0;}<br>&nbsp;&nbsp;&nbsp; private:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int a[101],size;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void Percdown(int p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int temp=a[p],child;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(;(p&lt;&lt;1)&lt;=size;p=child)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child=p&lt;&lt;1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(child+1&lt;=size &amp;&amp; d[a[child+1]]&lt;d[a[child]]) child++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(d[temp]&lt;d[a[child]]) break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a[p]=a[child];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handle[a[p]]=p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a[p]=temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handle[a[p]]=p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}h;<br><br>void init()<br>{<br>&nbsp;&nbsp;&nbsp; int i,j,c;<br>&nbsp;&nbsp;&nbsp; for(i=1;i&lt;=n;i++)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(j=1;j&lt;=n;j++) map[i][j]=0x7fffffff;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d[i]=0x7fffffff;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; d[1]=0;<br>&nbsp;&nbsp;&nbsp; while(m--)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scanf("%d%d%d",&amp;i,&amp;j,&amp;c);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; map[i][j]=map[j][i]=c;<br>&nbsp;&nbsp;&nbsp; }<br>}<br><br>void Relax(int num)<br>{<br>&nbsp;&nbsp;&nbsp; for(int i=1;i&lt;=n;i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(h.handle[i] &amp;&amp; map[num][i]!=0x7fffffff &amp;&amp; d[i]&gt;d[num]+map[num][i])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d[i]=d[num]+map[num][i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h.Percup(h.handle[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>}<br><br>void dijk()<br>{<br>&nbsp;&nbsp;&nbsp; h.Build(n);<br>&nbsp;&nbsp;&nbsp; while(!h.Empty()) Relax(h.DeleteMin());<br>}<br><br>int main()<br>{<br>&nbsp;&nbsp;&nbsp; while(scanf("%d%d",&amp;n,&amp;m) &amp;&amp; n+m)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dijk();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%d\n",d[n]);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; system("pause");<br>&nbsp;&nbsp;&nbsp; return 0;<br>} <br>---------------------<br>另一个版本<br><span style="FONT-SIZE: 12pt; FONT-FAMILY: Times">
<pre>#include &lt;stdio.h&gt;
const int SIZE= 30005, MAXX=2000000000;
int n,m,tail, dist[SIZE];
bool mark[SIZE];
struct Node
{
int id, val;
Node* next;
}node[SIZE];
struct Heap{
int id, val;
}heap[2*SIZE];
void insert(int a, int b, int val)
{
Node* p = new Node;
p-&gt;id = a;
p-&gt;val = val;
p-&gt;next = node[b].next;
node[b].next = p;
}
void heappush(int id, int val)
{
heap[++tail].id = id;
heap[tail].val = val;
int child, parent, temp;
child = tail;
while((parent = child/2)&gt;=1)
{
if(heap[child].val &lt; heap[parent].val)</span><span style="FONT-SIZE: 12pt; FONT-FAMILY: Times"> // child's val &lt; parent's val ; swap ,filter
{
temp = heap[child].id;
heap[child].id = heap[parent].id;
heap[parent].id = temp;
temp = heap[child].val;
heap[child].val = heap[parent].val;
heap[parent].val = temp;
child = parent;
}
else
break;
}
}
int heappop()
{
int child, parent, temp,ret;
ret = heap[1].id;
heap[1].id = heap[tail].id; </pre>
<pre>// swap the tail to the root
heap[1].val = heap[tail--].val;
parent = 1;
while((child=2*parent)&lt;=tail)
{
if(child+1&lt;=tail &amp;&amp; heap[child+1].val &lt; heap[child].val)
child++;
if(heap[child].val&lt;heap[parent].val)
{
temp = heap[child].id;
heap[child].id = heap[parent].id;
heap[parent].id = temp;
temp = heap[child].val;
heap[child].val = heap[parent].val;
heap[parent].val = temp;
parent = child;
}
else
break;
}
return ret;
}
int dijkstra(int s, int t)
{
int i;
for(i=1; i&lt;=n; i++)
{
dist[i] = MAXX;
mark[i] = false;
}
Node* p;
p = node[s].next;
while(p)
{
dist[p-&gt;id] = p-&gt;val;
heappush(p-&gt;id, p-&gt;val);
p = p-&gt;next;
}
mark[s] = true; dist[s] = 0;
for(i=1; i&lt;n; i++)
{
int pop = heappop();
while(mark[pop])
pop = heappop();
if(pop ==t || dist[pop]==MAXX)	break;
mark[pop] = true;
p = node[pop].next;
while(p)
{</pre>
<pre>if(!mark[p-&gt;id]&amp;&amp;</pre>
<pre>(dist[p-&gt;id]==MAXX || dist[pop]+p-&gt;val&lt; dist[p-&gt;id]))
{
dist[p-&gt;id] = dist[pop] + p-&gt;val;
heappush(p-&gt;id, dist[p-&gt;id]);
}
p = p-&gt;next;
}
}
return dist[t];
}
int main()
{
int i,a,b,c;
scanf("%d%d", &amp;n, &amp;m);
for(i=1; i&lt;=m; i++)
{
scanf("%d%d%d", &amp;a, &amp;b, &amp;c);
insert(a, b, c);
}
printf("%d\n", dijkstra(n,1));
return 0;
}
</pre>
</span>
<img src ="http://www.cppblog.com/luyulaile/aggbug/92739.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luyulaile/" target="_blank">luis</a> 2009-08-09 21:28 <a href="http://www.cppblog.com/luyulaile/archive/2009/08/09/92739.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>求最小支撑数 prim算法 实现</title><link>http://www.cppblog.com/luyulaile/archive/2009/08/09/92730.html</link><dc:creator>luis</dc:creator><author>luis</author><pubDate>Sun, 09 Aug 2009 11:52:00 GMT</pubDate><guid>http://www.cppblog.com/luyulaile/archive/2009/08/09/92730.html</guid><wfw:comment>http://www.cppblog.com/luyulaile/comments/92730.html</wfw:comment><comments>http://www.cppblog.com/luyulaile/archive/2009/08/09/92730.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luyulaile/comments/commentRss/92730.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luyulaile/services/trackbacks/92730.html</trackback:ping><description><![CDATA[#include&lt;stdio.h&gt;<br>#define MAX 0xfffffff<br>#define MaxVertex 21<br>//prim求最小支持树，多用于求边稠密网的最小支持树 时间复杂度O(n*n)n为顶点数; <br>#define&nbsp; vertextype int<br>int n;<br>bool s[MaxVertex];//该点是否被访问 <br>vertextype cost[MaxVertex];<br>vertextype dist[MaxVertex][MaxVertex];<br>void Init()<br>{<br>&nbsp;int i,j,a,b,c;<br>&nbsp; scanf("%d",&amp;n);//先输入点个数<br>&nbsp;&nbsp;&nbsp; for(i=1;i&lt;=n;i++)<br>&nbsp;&nbsp;&nbsp;&nbsp; for(j=1;j&lt;=n;j++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dist[i][j]=MAX;<br>&nbsp;&nbsp;&nbsp; while(scanf("%d%d%d",&amp;a,&amp;b,&amp;c),a||b||c)//0 0 0表示边输入结束 <br>&nbsp;&nbsp;&nbsp;&nbsp; dist[a][b]=dist[b][a]=c;<br>&nbsp;&nbsp;&nbsp; s[1]=true;//该点已经被访问<br>&nbsp;&nbsp;&nbsp; for(i=2;i&lt;=n;i++)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp; cost[i]=dist[1][i];<br>&nbsp;&nbsp;&nbsp;&nbsp; s[i]=false;//初始化为false<br>&nbsp;&nbsp;&nbsp; }<br>}<br>int main()<br>{<br>&nbsp;freopen("s.txt","r",stdin);<br>&nbsp;freopen("key.txt","w",stdout);&nbsp;<br>int i,j,k,m,a,b,c,best,min;<br>&nbsp;&nbsp;&nbsp; best=0; <br>&nbsp;Init(); <br>for(i=1;i&lt;n;i++)//i不能等于n，因为n-1条边 <br>{<br>&nbsp;min=MAX;<br>&nbsp;j=1;<br>&nbsp;for(k=2;k&lt;=n;k++)<br>&nbsp;&nbsp;if(cost[k]&lt;min&amp;&amp;(!s[k]))//&nbsp; (1)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;min=cost[k];<br>&nbsp;&nbsp;&nbsp;j=k;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;s[j]=true;<br>&nbsp;&nbsp;best+=min;<br>&nbsp;&nbsp;for(k=2;k&lt;=n;k++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if(dist[j][k]&lt;cost[k]&amp;&amp;(!s[k]))//可能出现已经访问过的点cost[k]保持原值，但这没有关系，以为在上面的处理步骤(1)中不对这些边处理 <br>&nbsp;&nbsp;//dist[j][j]&lt;cost[k]的比较则是为了重判集合V到V-U集合的点的距离，注意是整个集合V到各个未纳入V的点的距离！ <br>&nbsp;&nbsp;&nbsp;cost[k]=dist[j][k];<br>&nbsp;&nbsp;} <br>}<br>&nbsp;printf("%d\n",best);<br>&nbsp;return 0;<br>}<br>学以致用 joj 1170
<img src ="http://www.cppblog.com/luyulaile/aggbug/92730.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luyulaile/" target="_blank">luis</a> 2009-08-09 19:52 <a href="http://www.cppblog.com/luyulaile/archive/2009/08/09/92730.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>dijkstra的邻接表实现</title><link>http://www.cppblog.com/luyulaile/archive/2009/08/09/92683.html</link><dc:creator>luis</dc:creator><author>luis</author><pubDate>Sun, 09 Aug 2009 03:19:00 GMT</pubDate><guid>http://www.cppblog.com/luyulaile/archive/2009/08/09/92683.html</guid><wfw:comment>http://www.cppblog.com/luyulaile/comments/92683.html</wfw:comment><comments>http://www.cppblog.com/luyulaile/archive/2009/08/09/92683.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/luyulaile/comments/commentRss/92683.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luyulaile/services/trackbacks/92683.html</trackback:ping><description><![CDATA[#include&lt;iostream&gt;<br>using namespace std;<br>//求单源最小路径，不妨设源点为1，算法思想是 <br>//从未访问的顶点中选择dv最小的点（d为从该点到源点0的距离）令arcs[v][v]=1 <br>//考虑v的所有邻接顶点w，不断尝试若dv+weight(v,w)&lt;dw，则改变dw值 <br>//这里选择dv最小的很关键，因为最小，所以肯定是最短路径，其他的d会不断更新。 <br>&nbsp;#define&nbsp; MaxVertx 100//最多边长度 <br>&nbsp;#define MAX 1e+8<br>&nbsp;typedef char vertextype;<br>&nbsp;typedef float adjtype;<br>&nbsp;typedef struct{<br>&nbsp;&nbsp;int n;//顶点个数 <br>&nbsp;&nbsp;vertextype vertex[MaxVertx];<br>&nbsp;&nbsp;adjtype arcs[MaxVertx][MaxVertx];//邻接矩阵形式 <br>&nbsp;}Graph; <br>&nbsp;typedef struct{<br>&nbsp;&nbsp;vertextype vertex;//顶点信息<br>&nbsp;&nbsp;adjtype length;//最小长度&nbsp;<br>&nbsp;&nbsp;int&nbsp; prev;//最短路径上前驱结点编号 <br>&nbsp;}Path;<br>&nbsp;Path dist[MaxVertx];<br>&nbsp;Graph graph;<br>&nbsp;void init(Graph *pgraph,Path dist[])<br>&nbsp;{<br>&nbsp;&nbsp;int i;<br>&nbsp;&nbsp;dist[0].length=0;<br>&nbsp;&nbsp;dist[0].prev=0;<br>&nbsp;&nbsp;dist[0].vertex=pgraph-&gt;vertex[0];//第一个顶点的名称/编号<br>&nbsp;&nbsp;pgraph-&gt;arcs[0][0]=1; /* 表示顶点v0在集合U中 */<br>&nbsp;&nbsp;<br>&nbsp;&nbsp; for(i = 1; i &lt; pgraph-&gt;n; i++)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 初始化集合V-U中顶点的距离值 */<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;dist[i].length=pgraph-&gt;arcs[0][i];<br>&nbsp;&nbsp;&nbsp;&nbsp;dist[i].vertex=pgraph-&gt;vertex[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;if(dist[i].length!=MAX)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dist[i].prev=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dist[i].prev=-1;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;}<br>&nbsp;void dijkstra(Graph graph,Path dist[])<br>&nbsp;{<br>&nbsp;&nbsp;int i,j,minvex;<br>&nbsp;&nbsp;adjtype min;<br>&nbsp;&nbsp;init(&amp;graph,dist); /* 初始化，此时集合U中只有顶点v0*/<br>&nbsp;&nbsp;for(i=1;i&lt;graph.n;i++)//每个dist[]都要求 不一定会执行n次，可能会break出来 <br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;min=MAX;<br>&nbsp;&nbsp;&nbsp;minvex=0;<br>&nbsp;&nbsp;&nbsp;for(j=1;j&lt;graph.n;j++)/*在VU中选出距离值最小顶点*/<br>&nbsp;&nbsp;&nbsp;if(graph.arcs[j][j]==0&amp;&amp;dist[j].length&lt;min)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;min=dist[j].length;<br>&nbsp;&nbsp;&nbsp;&nbsp;minvex=j;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;if(minvex==0)break;/* 从v0没有路径可以通往集合VU中的顶点 */<br>&nbsp;&nbsp;&nbsp;graph.arcs[minvex][minvex]=1;//表示已经访问过了，不属于VU集合<br>&nbsp;&nbsp;&nbsp;for(j=1;j&lt;graph.n;j++)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;if(graph.arcs[j][j]==1)continue;<br>&nbsp;&nbsp;&nbsp;&nbsp;if(dist[j].length &gt; dist[minvex].length + graph.arcs[minvex][j])//如果不相邻，则arcs[minvex][minvex]=+无穷 <br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dist[j].length = dist[minvex].length + graph.arcs[minvex][j];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dist[j].prev = minvex;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;} <br>&nbsp;&nbsp;}<br>&nbsp;}<br>&nbsp;void initgraph()//初始化矩阵 <br>&nbsp;{<br>&nbsp;int i,j;<br>&nbsp;&nbsp;&nbsp; graph.n=6;<br>&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; graph.n; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (j = 0; j &lt; graph.n; j++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; graph.arcs[i][j] = (i == j ? 0 : MAX);<br>&nbsp;&nbsp;&nbsp; graph.arcs[0][1] = 50;<br>&nbsp;&nbsp;&nbsp; graph.arcs[0][2] = 10;<br>&nbsp;&nbsp;&nbsp; graph.arcs[1][2] = 15;<br>&nbsp;&nbsp;&nbsp; graph.arcs[1][4] = 5;<br>&nbsp;&nbsp;&nbsp; graph.arcs[2][0] = 20;<br>&nbsp;&nbsp;&nbsp; graph.arcs[2][3] = 15;<br>&nbsp;&nbsp;&nbsp; graph.arcs[3][1] = 20;<br>&nbsp;&nbsp;&nbsp; graph.arcs[3][4] = 35;<br>&nbsp;&nbsp;&nbsp; graph.arcs[4][3] = 30;<br>&nbsp;&nbsp;&nbsp; graph.arcs[5][3] = 3;<br>&nbsp;&nbsp;&nbsp; graph.arcs[0][4] = 45;&nbsp;<br>&nbsp;}<br>&nbsp; int main()<br>&nbsp; {<br>&nbsp; //freopen("s.txt","r",stdin);<br>&nbsp; //freopen("key.txt","w",stdout);<br>&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp; initgraph();<br>&nbsp;&nbsp;&nbsp; dijkstra(graph, dist);<br>&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; graph.n; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("(%.0f %d)", dist[i].length,dist[i].prev);<br>&nbsp;&nbsp;&nbsp; getchar();<br>&nbsp;return 0;<br>&nbsp; }<br>
<img src ="http://www.cppblog.com/luyulaile/aggbug/92683.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luyulaile/" target="_blank">luis</a> 2009-08-09 11:19 <a href="http://www.cppblog.com/luyulaile/archive/2009/08/09/92683.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>joj 2035 Leaf Nodes</title><link>http://www.cppblog.com/luyulaile/archive/2009/07/14/90082.html</link><dc:creator>luis</dc:creator><author>luis</author><pubDate>Tue, 14 Jul 2009 14:14:00 GMT</pubDate><guid>http://www.cppblog.com/luyulaile/archive/2009/07/14/90082.html</guid><wfw:comment>http://www.cppblog.com/luyulaile/comments/90082.html</wfw:comment><comments>http://www.cppblog.com/luyulaile/archive/2009/07/14/90082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/luyulaile/comments/commentRss/90082.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/luyulaile/services/trackbacks/90082.html</trackback:ping><description><![CDATA[Leaf Nodes
<hr>
<table cellSpacing=3 cellPadding=3 width="75%" border=1>
    <colgroup style="COLOR: red; TEXT-ALIGN: center" span=7>
    <tbody>
        <tr>
            <th height=40>Status</th>
            <th>In/Out</th>
            <th>TIME Limit</th>
            <th>MEMORY Limit</th>
            <th>Submit Times</th>
            <th>Solved Users</th>
            <th>JUDGE TYPE</th>
        </tr>
        <tr>
            <td align=middle height=40><span id=probinfo_placeholder><img height=20 src="http://acm.jlu.edu.cn/joj/images/ok1.gif" width=20></span></td>
            <td>stdin/stdout</td>
            <td>1s</td>
            <td>10240K</td>
            <td>222</td>
            <td>102</td>
            <td>Standard</td>
        </tr>
    </tbody>
</table>
<div class=prob_text>
<p>Kate is learning about binary tree. She think she know everything you know about binary trees. Wait, you don't know binary tree? Find a book about data structures, and it will just take you about three minutes. Now here is a binary tree: </p>
<pre>                                    3
/ \
/   \
2     4
/ \     \
/   \     \
0     1     6
/
/
5
</pre>
<p>Kate think she also know something that you may not notice. First, for some type of binary trees, only the leaf nodes have the meaning (leaf node is the node which has no sub trees, for the tree above, the leaf nodes are 0 1 5), an example is the Huffman Tree. Second, she guess that if you know the preorder traversal and the postorder traversal of a binary tree, you can ensure the leaf node of the tree, and their order. </p>
<p>For the tree above, the preorder travesal is 3 2 0 1 4 6 5 and the postorder travesal is 0 1 2 5 6 4 3, the leaf nodes in order(from left to right) are 0 1 5. </p>
<p>But now the problem is she just guess it, if you can find a way to print a tree's leaf nodes in order using its preorder traversal and postorder traversal, you can say "she is right!" </p>
<h3>Input Specification</h3>
<p>The input file will contain one or more test cases. In each test case there is a integer n (0&lt;=n &lt;= 10000), indicating the tree have n nodes, then followed two lists of integers, either contains n integers in the range of 0 and n-1 (both included), the first list is the preorder traversal, and the other is the postorder traversal. </p>
<p>Input is terminated by an interger -1; </p>
<h3>Output Specification</h3>
<p>For each test case, print the tree's leaf nodes in order, each in a line.</p>
<h3>Sample Input</h3>
<pre>7
3 2 0 1 4 6 5
0 1 2 5 6 4 3
-1</pre>
<h3>Sample Output</h3>
<pre>0
1
5</pre>
根据一个重要结论，无论是先根还是后根遍历，左子树的结点总是出现在右子树结点的前面<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;G&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp; \&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; F&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp; \&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; K&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; H&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp; \&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; E&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; J&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; I&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; <br>&nbsp; 不论先根后根，左子树的结点总是出现在右子树结点的前面。&nbsp;&nbsp; <br>&nbsp; G为根树，先根次序时G后跟F，后根次序时F前有DIAEKF，故DIAEKF为G的左子树的结点，<br>&nbsp; CJHB为G的右子树的结点。且左右子树的先根序为：FKDIAE，BCHJ。<br>&nbsp; 递归处理两子树即可搞定<br><br>void&nbsp; find(int preb,int pree,int postb,int poste)&nbsp; <br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;int i=s(pre,post[poste-1]);<br>&nbsp;&nbsp;int j=s(post,pre[preb+1]);<br>//添加处理的代码<br>&nbsp;//判断是否有左/右支<br><br>&nbsp;&nbsp;&nbsp;&nbsp;find(preb+1,i-1,postb,j);<br>&nbsp;&nbsp;find(i,pree,j+1,poste-1);<br>&nbsp;&nbsp; }<br><span style="COLOR: red">但是上面的思路是<strong>错误</strong>的！！！！！！！！！！！！！！</span><br>只知道先序和后序不能能推出树来 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 只有中序和先序或者中序和后序才可以 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; 不然只知道根节点,但是哪些是左子树哪些是右子树就不知道了<br>比如先序时1234 &nbsp; <br>&nbsp; 后序是4321的二叉树有8种比如： &nbsp; <br>&nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; \ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; <br>&nbsp; &nbsp; / &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / &nbsp; <br>&nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; <br>&nbsp; &nbsp; \ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / &nbsp; <br>&nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; 4<br><br>正确思路：先遍历后根次序，第一个一定为叶子，设为当前结点，然后依次检测，如果该点在先根序列中位于当前节点的后面，则为叶子节点，同时更新当前结点。</div>
<img src ="http://www.cppblog.com/luyulaile/aggbug/90082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/luyulaile/" target="_blank">luis</a> 2009-07-14 22:14 <a href="http://www.cppblog.com/luyulaile/archive/2009/07/14/90082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>