<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;C0EDQ3c7fip7ImA9WxBUFUg.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472</id><updated>2010-03-02T13:41:12.906-04:00</updated><title>ALLgoritmos - Tudo sobre Algoritmos e Programação</title><subtitle type="html">Explanar sobre Algoritmos, Programação, Maratona de Programação, Problemas Resolvidos sobre Maratona de Programação, MPI, Novidades de Tecnologia e Afins</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.allgoritmos.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>148</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/allgoritmos" /><feedburner:info uri="allgoritmos" /><feedburner:emailServiceId>allgoritmos</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;DUYBRHw6cSp7ImA9WxNbFUw.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-8497624083761408481</id><published>2009-11-18T01:01:00.002-03:00</published><updated>2009-11-18T01:05:55.219-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-18T01:05:55.219-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="notícias" /><category scheme="http://www.blogger.com/atom/ns#" term="busca google" /><title>Microsoft vs Google, a guerra dos buscadores continua</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rjLVs28c5JaMpcpSIYjL1YyY6FU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rjLVs28c5JaMpcpSIYjL1YyY6FU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rjLVs28c5JaMpcpSIYjL1YyY6FU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rjLVs28c5JaMpcpSIYjL1YyY6FU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://i722.photobucket.com/albums/ww221/allgoritmos/bing-logo-300x231.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="154" src="http://i722.photobucket.com/albums/ww221/allgoritmos/bing-logo-300x231.jpg" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;Novo buscador da Microsoft, &lt;b&gt;o Bing&lt;/b&gt;, aumentou a sua fatia no mercado de busca Norte-Americano em outubro, com crescimento de 0,5% o Bing está muito próximo dos 10% segundo a empresa de monitoramento online da comScore.&lt;br /&gt;
&lt;br /&gt;
Foi o quinto mês consecutivo de ganhos modestos por parte do Bing, que a Microsoft lançou em junho acompanhado por cerca de &lt;b&gt;U$ 100 em campanha publicitária a fim de desafiar a gigante Google&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Este crescimento deve-se a várias inovações e ajustes que a Microsoft realizou no Bing nos últimos meses.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://i722.photobucket.com/albums/ww221/allgoritmos/logo-adsense-peq.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://i722.photobucket.com/albums/ww221/allgoritmos/logo-adsense-peq.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;O buscador da &lt;b&gt;Google teve crescimento de 0,5%&lt;/b&gt; também em Outubro e quem saiu perdendo foi a parceira da Microsoft, a Yahoo, que teve declínio de 0,8%.&lt;br /&gt;
&lt;br /&gt;
O mercado dos buscadores cada dia mais agitado e nós, utilizadores, é que ganhamos com isso, cada dia teremos serviços de busca mais precisos.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-8497624083761408481?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/iKyWsOTCBMA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/8497624083761408481/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/11/microsoft-vs-google-guerra-dos-buscador.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/8497624083761408481?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/8497624083761408481?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/iKyWsOTCBMA/microsoft-vs-google-guerra-dos-buscador.html" title="Microsoft vs Google, a guerra dos buscadores continua" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/11/microsoft-vs-google-guerra-dos-buscador.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIHQX04eyp7ImA9WxNbEE4.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-6295189326939047436</id><published>2009-11-12T11:52:00.000-03:00</published><updated>2009-11-12T11:52:10.333-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-12T11:52:10.333-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="novidades" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>Navegador Google Maps para Android</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/z0IylUIXgJIQCGNuv_8lo5-LkQg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/z0IylUIXgJIQCGNuv_8lo5-LkQg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/z0IylUIXgJIQCGNuv_8lo5-LkQg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/z0IylUIXgJIQCGNuv_8lo5-LkQg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;O &lt;a href="http://googleblog.blogspot.com/2009/10/announcing-google-maps-navigation-for.html"&gt;blog do Google&lt;/a&gt; anunciou que o Navegador Google Maps estará disponível no Android 2.0. &lt;br /&gt;
&lt;br /&gt;
O primeiro telefone celular que vem com o Android 2.0 é o &lt;b&gt;Motorola Droid&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
"Esta nova funcionalidade vem com tudo que você esperaria encontrar em um sistema de navegação GPS, como visualizações em 3D, orientação passo-a-passo por voz e reencaminhamento automático. Mas, ao contrário da maioria dos sistemas de navegação, o Navegador Google Maps foi construído a partir do solo em relação a ligação do seu telefone com a Internet ". E ao contrário de outros sistemas de navegação, &lt;b&gt;é grátis&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Algumas fotos:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://i722.photobucket.com/albums/ww221/allgoritmos/google-navigation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://i722.photobucket.com/albums/ww221/allgoritmos/google-navigation.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://googleblog.blogspot.com/2009/10/announcing-google-maps-navigation-for.html"&gt;Fonte&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-6295189326939047436?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/_y0Vhhw1ZSE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/6295189326939047436/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/11/navegador-google-maps-para-android.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/6295189326939047436?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/6295189326939047436?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/_y0Vhhw1ZSE/navegador-google-maps-para-android.html" title="Navegador Google Maps para Android" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/11/navegador-google-maps-para-android.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8DRng4eip7ImA9WxNVEEw.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-5214660809650787897</id><published>2009-10-20T00:54:00.000-03:00</published><updated>2009-10-20T00:54:37.632-03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-20T00:54:37.632-03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="notícias" /><title>Windows 7 vs. Mac Snow Leopard: Debate entre Executivos</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8pcYIMKr3DeBRdEs1nHc12GFpmA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8pcYIMKr3DeBRdEs1nHc12GFpmA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8pcYIMKr3DeBRdEs1nHc12GFpmA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8pcYIMKr3DeBRdEs1nHc12GFpmA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;
&lt;i&gt;Dois executivos um de cada sistema operacional se enfrentam neste debate virtual &lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Você já imaginou o que seria se você pudesse ver os executivos de ambas as empresas (Microsoft e Apple) discutindo sobre estes produtos? Não através de comerciais, mas sim com um debate honesto mostrando as vantagens de cada produto?&lt;br /&gt;
&lt;br /&gt;
Isso provavelmente nunca irá acontecer porém o site &lt;a href="http://draft.blogger.com/www.pcmag.com" target="_blank"&gt;PCMag&lt;/a&gt; entrevistou dois grandes executivos: Brian Crollum da Apple e Jay Paulus da Microsoft.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://i722.photobucket.com/albums/ww221/allgoritmos/apple-vs-pc.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://i722.photobucket.com/albums/ww221/allgoritmos/apple-vs-pc.jpg" /&gt;&lt;/a&gt;Os dois responderam perguntas sobre seus produtos e o site PCMag intercalou as respostas e criou um &lt;b&gt;debate virtual&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Configura as principais perguntas:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Tema: Qual é o seu Diferencial?&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Entrevistador&lt;/b&gt;: Na corrida para construir o melhor sistema operacional, onde cada um pensa que está? O que o diferencia? Sr. Croll? &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Brian Crollum (Apple)&lt;/b&gt;: Mac OS X é muito mais simples do que o Windows. Nós estamos mais avançados do ponto de vista tecnológico. Windows 7 ainda tem DLL’s, registros, ainda tem a desfragmentação, ainda precisa de ativação. Nós não fazemos nossos usuários entrarem com códigos de ativação. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Entrevistador&lt;/b&gt;: A Microsoft fez muitas coisas para o Windows 7, mas não conseguiu alterar alguns dos fundamentos como a DLL e o Registro. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: Então o quê? Sim, temos o registro e a DLL, mas isso não é algo que falamos. Nós focamos nosso trabalho em torno de confiabilidade e desempenho. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Entrevistador&lt;/b&gt;: E sobre a ativação? &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: A Apple tem um modelo diferente. Eles ganham um monte de dinheiro no hardware e ganham novamente no sistema operacional. Estamos vendendo o sistema operacional. Usamos a ativação para garantir que tenhamos versões originais rodando fora dos EUA.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Tema: Preços&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Entrevistador&lt;/b&gt;: Vamos falar sobre os preços. Há sistemas operacionais livres por aí, como o Linux, mas, como podemos ver partes de mercado livre não se traduz necessariamente em massa e grande adoção pelo mercado. Como vocês vêem a questão do preço? &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Brian Crollum (Apple)&lt;/b&gt;: Com o Snow Leopard, o preço de upgrade é de $29 para usuários do Leopard ou $49 para um pacote familiar com cinco licenças. Com o Windows 7 Ultimate, a atualização é de $119 para o Home Premium e $199 para profissionais de software, o que é realmente caro. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Entrevistador&lt;/b&gt;: Jay, eu sei que a Microsoft tem um plano de $30 para estudantes. O que mais você tem a dizer sobre os preços? &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Jay Paulus (Microsoft)&lt;/b&gt;: Snow Leopard é muito mais parecido com um pacote de serviços (um upgrade) e a Apple está cobrando $29 por ele. Nós não fazemos isso. Windows 7 demonstra grande valor para o cliente e com preços bastante atraentes. Com a Apple você vai ter que comprar o seu caro hardware só para entrar no “jogo”.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.pcmag.com/article2/0,2817,2354364,00.asp" target="_blank"&gt; Veja a entrevista completa&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-5214660809650787897?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/yz_KaAhcPFQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/5214660809650787897/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/windows-7-vs-mac-snow-leopard-debate.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/5214660809650787897?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/5214660809650787897?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/yz_KaAhcPFQ/windows-7-vs-mac-snow-leopard-debate.html" title="Windows 7 vs. Mac Snow Leopard: Debate entre Executivos" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/windows-7-vs-mac-snow-leopard-debate.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAEQHs8cCp7ImA9WxNWFk8.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-4881839686236809956</id><published>2009-10-15T13:45:00.000-04:00</published><updated>2009-10-15T13:45:01.578-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-15T13:45:01.578-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="personagens" /><title>[Personagens da Computação] Turing, Alan Mathison</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JVvG8bYNTcJybbXNTJzjs7MhxRA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JVvG8bYNTcJybbXNTJzjs7MhxRA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JVvG8bYNTcJybbXNTJzjs7MhxRA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JVvG8bYNTcJybbXNTJzjs7MhxRA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;O que dizer de um homem que &lt;b&gt;criou a teoria da computação&lt;/b&gt; e, não satisfeito, arregaçou as mangas e assumiu um papel central na construção dos primeiros computadores? De um matemático que venceu com cálculos as bombas de Hitler? No mínimo, que merecia uma estátua no Vale do Silício, um enterro com glórias de herói, que seu nome deveria virar nome de ruas, avenidas, universidades. &lt;b&gt;Mas esse homem morreu esquecido&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
Sua história só é conhecida graças à biografia monumental, escrita em 1983 pelo matemático Andrew Hodges. Mas estou me adiantando. Comecemos do começo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;História do grande Alan Mathison Turing (1912-1954)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Alan Turing nasceu em &lt;b&gt;1912&lt;/b&gt;, em Londres. Era um garoto tímido, sem muito talento para o convívio social e sem muito cuidado com a aparência. Na escola, destacava-se apenas por ser esquisito introvertido, irônico, pouco disposto a respeitar regras. Um cara tão estranho que, no futebol, &lt;b&gt;gostava de ser bandeirinha&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Aos 16 anos, conheceu um garoto muito inteligente chamado Christopher Morcom. Naquele momento, Turing descobriu um fato que mudou sua vida (e, novamente me adiantando, aproximou sua morte): ele era gay. Chris morreu em 1930 de pneumonia bovina (transmitida pelo leite). Essa primeira paixão marcaria Alan para sempre. Foi em parte devido à vontade de continuar o legado intelectual do amigo que Turing se aplicou nos estudos, na faculdade de Matemática, e tornou-se conhecido dos professores de Cambridge por seu raciocínio brilhante.&lt;br /&gt;
&lt;br /&gt;
Em 1937, publicou um artigo Sobre as Máquinas Computáveis que teve uma importância enorme para a matemática pura: nele, provava que existiam cálculos impossíveis de serem feitos. Mas também trazia uma aplicação prática que ninguém, na época, percebeu. &lt;b&gt;Turing imaginara uma máquina capaz de fazer todos os cálculos possíveis&lt;/b&gt;, desde que lhe dessem as instruções adequadas. O artigo não fazia menção a chips ou processadores continha apenas fórmulas matemáticas. Mas a descrição era exatamente daquilo que, mais tarde, mudaria o mundo com o nome de computador.&lt;br /&gt;
&lt;br /&gt;
Por falar em mudar o mundo, naquele momento surgia um austríaco obcecado por impor suas idéias ao planeta: &lt;b&gt;Adolf Hitler&lt;/b&gt;. Um de seus trunfos era uma máquina chamada Enigma um sistema de engrenagens capaz de embaralhar as letras das mensagens antes da transmissão por telégrafo. Os alemães consideravam esse código indecifrável. Caberia a Turing, convocado em 1939 pelo exército britânico, decifrá-lo.&lt;br /&gt;
&lt;br /&gt;
Um ano mais tarde, a guerra parecia uma barbada para Hitler. A Europa continental havia caído e as ilhas britânicas estavam, bem, ilhadas dependiam dos navios que cruzavam o Atlântico com armas e mantimentos americanos. Os submarinos alemães afundavam 200.000 toneladas de embarcações todo mês e o único jeito de descobrir a posição dos submarinos era decifrar suas mensagens.&lt;br /&gt;
&lt;br /&gt;
Turing &lt;b&gt;tirou a cabeça das máquinas teóricas e sujou as mãos na graxa de engenhocas reais&lt;/b&gt;. Uma delas, o Colossus, é tataravó do PC no qual digito agora. No começo, elas demoravam semanas para tornar uma mensagem compreensível. Mas, em 1942, os ingleses já decodificavam 50 000 mensagens por mês, uma por minuto. Os submarinos alemães eram abatidos como moscas. O preconceituoso Hitler, cuja equipe olímpica tinha sido derrotada em 1936 pelo atleta negro americano Jesse Owens, &lt;b&gt;perdia a guerra para um intelectual homossexual&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
O ditador nunca soube disso. Aliás, nem a mãe de Turing. &lt;b&gt;Sua participação na guerra permaneceu secreta por décadas&lt;/b&gt;. Tanto que, quando a polícia o prendeu em 1952 por grande indecência em outras palavras, homossexualismo , ninguém o defendeu dizendo que se tratava de um herói de guerra. Para enfrentar o julgamento, teve que se afastar de suas pesquisas sobre inteligência artificial Turing é inventor de um teste até hoje usado para decidir se uma máquina pensa. Acabou condenado a um tratamento com hormônios que arruinou seu físico.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Na noite de 7 de junho de 1954&lt;/b&gt;, atormentado, o matemático deitou-se na cama e mordeu uma maçã. Na manhã seguinte, não acordou. A fruta havia sido mergulhada numa jarra de cianeto.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Autor:&lt;/b&gt; Editor da revista Superinteressante &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Finalmente em 2009 o Reino Unido pede desculpas póstumas a Alan Turing&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
O primeiro-ministro britânico, Gordon Brown, ofereceu um &lt;b&gt;pedido póstumo de desculpas ao matemático Alan Turing&lt;/b&gt;, pelo tratamento "&lt;b&gt;desumano&lt;/b&gt;" que recebeu das autoridades britânicas e que o &lt;b&gt;levou ao suicídio em 1954&lt;/b&gt;. Turing atuou com a equipe responsável por quebrar o código secreto Enigma, usado pelos alemães na II Guerra Mundial, e produziu trabalhos teóricos que estão na base de boa parte da informática moderna e das pesquisas sobre inteligência artificial.&lt;br /&gt;
&lt;br /&gt;
Homossexual, Turing foi processado numa época em que essa conduta era considerada crime no Reino Unido, e forçado a se submeter a um tratamento com hormônios.&lt;br /&gt;
&lt;br /&gt;
Em 1952, Turing foi condenado por indecência, por ter mantido relações sexuais com outro homem, e teve de optar entre ir para a cadeia ou sofrer "castração química" - a injeção de hormônios para suprimir a libido. Seus privilégios de segurança foram revogados &lt;b&gt;ele foi impedido de continuar a trabalhar para o governo&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Dois anos depois, cometeu suicídio, comendo uma &lt;b&gt;maça envenenada&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
No momento em que o Reino Unido marca dos 70 anos do início da guerra em 1939 - lembrada como "a melhor hora" do povo britânico - Brown disse que Turing "merecia algo muito melhor" do que o tratamento que recebeu da sociedade no pós-guerra.&lt;br /&gt;
&lt;br /&gt;
"Não é exagero dizer que, sem sua contribuição extraordinária, a história da II Guerra Mundial poderia ter sido muito diferente", afirmou o primeiro-ministro. "Ele realmente foi um dos indivíduos para quem podemos apontar e dizer que suas contribuições únicas ajudaram a virar a maré da guerra".&lt;br /&gt;
&lt;br /&gt;
Brown disse que Turing foi "de fato, &lt;b&gt;julgado por ser gay&lt;/b&gt;". A homossexualidade continuou a ser ilegal no Reino Unido até 1967.&lt;br /&gt;
&lt;br /&gt;
"A dívida de gratidão para com ele torna ainda mais horrível, portanto, que tenha sido tratado de modo tão desumano", disse Brown. "Sentimos muito, você merecia algo muito melhor".&lt;br /&gt;
&lt;br /&gt;
As desculpas de Brown seguem-se a uma petição online que atraiu mais de &lt;b&gt;30.000 assinaturas&lt;/b&gt;, incluindo o romancista Ian McEwan e o cientista Richard Dawkins.&lt;br /&gt;
&lt;br /&gt;
O cientista John Graham-Cumming disse ter começado a campanha porque "Turing não era tão conhecido no Reino Unido quanto acho que deveria ser, como um herói da guerra um grande matemático". Graham-Cumming disse ainda que não seria um exagero chamar Turing de "&lt;b&gt;pai da computação&lt;/b&gt;".&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fontes:&lt;br /&gt;
[1] Alan Turing&lt;/b&gt; (&lt;a href='http://super.abril.com.br/superarquivo/2000/conteudo_119009.shtml' target='_blank'&gt;link&lt;/a&gt;)&lt;br /&gt;
Perfil e biografia do inventor do computador&lt;br /&gt;
&lt;b&gt;[2] Reino Unido pede desculpas póstumas a Alan Turing&lt;/b&gt; (&lt;a href='http://m.estadao.com.br/noticias/vidae,reino-unido-pede-desculpas-postumas-a-alan-turing,433322.htm' target='_blank'&gt;link&lt;/a&gt;)&lt;br /&gt;
Homossexual, o gênio da matemática foi processado numa época em que essa conduta era considerada crime&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-4881839686236809956?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/CQp2iTJRcAI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/4881839686236809956/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/personagens-da-computacao-turing-alan.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4881839686236809956?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4881839686236809956?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/CQp2iTJRcAI/personagens-da-computacao-turing-alan.html" title="[Personagens da Computação] Turing, Alan Mathison" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/personagens-da-computacao-turing-alan.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EHQ3c4fyp7ImA9WxNWFkw.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-9089581098632779741</id><published>2009-10-15T11:13:00.000-04:00</published><updated>2009-10-15T11:13:52.937-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-15T11:13:52.937-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="notícias" /><title>Google Wave é mais seguro que e-mail</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9HrccFifg7Q5PyL-lO-jz1lTj4s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9HrccFifg7Q5PyL-lO-jz1lTj4s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9HrccFifg7Q5PyL-lO-jz1lTj4s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9HrccFifg7Q5PyL-lO-jz1lTj4s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;b&gt;Google Wave&lt;/b&gt;, a plataforma de colaboração em tempo real da Google atualmente em fase beta é mais segura que o tradicional e-mail, afirma a empresa. &lt;br /&gt;
&lt;br /&gt;
De acordo com Greg D’alesandre, gerente do Google Wave, essa segurança é produto da concentração da Google em enfrentar questões de privacidade e segurança. Pensando nisso o sistema está sendo construído já pensando nestas características, o que pode fazer o desenvolvimento ser mais lento, mas irá prover maior segurança a seus usuários.&lt;br /&gt;
&lt;br /&gt;
Greg D’alesandre detalhou diversas características de segurança do Wave. As três principais características são: &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Características para evitar falsificação &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Wave tem vários níveis de segurança que são projetados para evitar a falsificação de e-mail. Spoofing, ou seja, quando você recebe um e-mail que afirma ser de uma pessoa ou empresa que você conhece, mas é na verdade de outra pessoa - um hacker na maioria dos casos. &lt;br /&gt;
&lt;br /&gt;
"Você sabe que você está recebendo a onda da pessoa que está enviando a você e não nada foi alterado pelo caminho. Este é um problema muito presente nas tecnologias de comunicação atual - os dados podem ser alterados durante fluxo e você nunca irá saber", disse D’alesandre. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;HTTPS ativado por padrão&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Para uma camada adicional de segurança, todo o tráfego de onda é por padrão codificado via HTTPS, um protocolo para comunicações seguras.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Lista Branca&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Usuários do Wave serão capazes de selecionar as pessoas que querem colaborar e colocá-los em uma lista branca de pessoas aprovadas. Somente aqueles que estão na lista terão a possibilidade de contatá-los através das ondas e todos os outros serão ignorados.&lt;br /&gt;
&lt;br /&gt;
As duas primeiras características já estão em funcionamento e a terceira estará em breve.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fonte: &lt;/b&gt;&lt;a href="http://www.readwriteweb.com/archives/google_wave_more_secure_than_traditional_email.php" target="_blank"&gt;RWW&lt;/a&gt; &lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-9089581098632779741?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/ZhurwZsHQbI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/9089581098632779741/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/google-wave-e-mais-seguro-que-e-mail.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/9089581098632779741?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/9089581098632779741?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/ZhurwZsHQbI/google-wave-e-mais-seguro-que-e-mail.html" title="Google Wave é mais seguro que e-mail" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/google-wave-e-mais-seguro-que-e-mail.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkICSH49eip7ImA9WxNWFUk.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-8880178324813288954</id><published>2009-10-14T14:11:00.001-04:00</published><updated>2009-10-14T14:22:49.062-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-14T14:22:49.062-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="personagens" /><title>[Personagens da Computação] Dijkstra, Edsger Wybe</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RkewZ9tNC9ChnKJbdHbSHtDLkBY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RkewZ9tNC9ChnKJbdHbSHtDLkBY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RkewZ9tNC9ChnKJbdHbSHtDLkBY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RkewZ9tNC9ChnKJbdHbSHtDLkBY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align='justify'&gt;Com este artigo início uma série sobre grandes personagens da história da computação.&lt;br /&gt;
&lt;br /&gt;
Sugestões de personagens podem ser feitas através dos comentários e eu farei o possível para encontrar algumas informações sobre o mesmo e postar aqui.&lt;br /&gt;
&lt;br /&gt;
Creio que seja importante valorizar o nosso passado e entender de onde vieram esses conceitos que conhecemos e usamos hoje em dia.&lt;br /&gt;
&lt;br /&gt;
Começaremos pela história do Dijkstra [pronuncie algo entre "Dêcstra" e "Dêicstra"]:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A história do grande Edsger Wybe Dijkstra (1930-2002)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;"A arte de programar consiste em organizar e dominar a complexidade" - Edsger W. Dijkstra&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
O professor &lt;b&gt;Edsger Wybe Dijkstra, um pioneiro notável da ciência e da indústria da computação&lt;/b&gt;, faleceu após uma longa luta contra o câncer, em 6 de agosto de 2002 em Nuenen, nos Países Baixos.&lt;br /&gt;
&lt;br /&gt;
Dijkstra nasceu em &lt;b&gt;1930&lt;/b&gt; em Rotterdam, filho de um pai químico e uma mãe matemática. Graduou-se no Gymnasium Erasmianum em Rotterdam e obteve graduações na matemática e na física teórica da universidade de Leyden, e um &lt;b&gt;Ph.D. em ciência da computação da universidade de Amsterdã&lt;/b&gt;. Trabalhou como programador no centrum de Mathematisch, Amsterdã, 1952-1962; era professor de matemática, universidade de Eindhoven de tecnologia, 1962-1984; e era um companheiro da pesquisa da corporação de Burroughs, 1973-1984. Deteve a cadeira centennial de Schlumberger em ciências da computação na universidade de Texas em Austin, 1984-1999, e aposentou-se como professor Emeritus em 1999.&lt;br /&gt;
&lt;br /&gt;
A Dijkstra foi concedido em &lt;b&gt;1972 o prêmio ACM Turing&lt;/b&gt;, visto freqüentemente como o prêmio Nobel para a computação. Era membro da academia real de artes e ciências dos Países Baixos, da academia de artes e ciências americana, e um distinto companheiro da sociedade britânica de computação. Recebeu em 1974 o prêmio AFIPS Harry Goode, em 1982 o prêmio de pioneiro da computação do IEEE, e em 1989 o prêmio ACM SIGCSE para contribuições proeminentes à instrução da ciência da computação. A universidade de Atenas de economia concedeu-lhe um doutorado honorário em 2001. Em 2002, a fundação de C&amp;C do Japão reconheceu Dijkstra "por suas contribuições abrindo caminho ao estabelecer base científica para o software de computador com a pesquisa &lt;b&gt;criativa da teoria básica do software, da teoria do algoritmo, da programação estruturada, e dos semáforos&lt;/b&gt;".&lt;br /&gt;
&lt;br /&gt;
Dijkstra é reconhecido por suas contribuições à metodologia matemática. É responsável pela &lt;b&gt;idéia de construção de sistemas operacionais como processos seqüenciais explicitamente sincronizados&lt;/b&gt;, pelo desenvolvimento formal de programas de computador, e para as fundações intelectuais para o controle disciplinado do não determinismo. É bem conhecido por seu &lt;b&gt;algoritmo de caminho mais curto surpreendentemente eficiente&lt;/b&gt; e por ter projetado e codificado o primeiro compilador do Algol 60. &lt;b&gt;Era notoriamente o líder da abolição do comando GOTO na programação.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Dijkstra era um escritor prodígio. Sua coleção inteira de mais de mil e trezentos trabalhos manuscritos foi digitalizada e estão acessíveis em&lt;br /&gt;
&lt;a href='http://www.cs.utexas.edu/users/EWD' target='_blank'&gt;http://www.cs.utexas.edu/users/EWD&lt;/a&gt;. Correspondeu-se também regularmente com as centenas dos amigos e dos colegas através dos anos, &lt;b&gt;não por email, mas por cartas convencionais, as quais tinha maior gosto&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Dijkstra era notório por sua sagacidade, eloqüência, e a intimidade com palavras, como em sua observação &lt;b&gt;"a pergunta de se os computadores podem pensar é como a pergunta de se os submarinos podem nadar"&lt;/b&gt;; seu conselho a um pesquisador promissor, que perguntou como selecionar um tópico para a pesquisa: &lt;b&gt;"faça somente o que somente você pode fazer"&lt;/b&gt;; e sua observação em sua palestra da concessão de Turing "em sua capacidade como uma ferramenta, computadores serão mais uma ondulação na superfície de nossa cultura. Em sua capacidade como o desafio intelectual, são sem precedentes na história cultural da humanidade".&lt;br /&gt;
&lt;br /&gt;
Dijkstra enriqueceu a língua da computação com muitos conceitos e frases, como a &lt;b&gt;programação estruturada&lt;/b&gt;, separação dos interesses, sincronização, &lt;b&gt;deadlock, jantar dos filósofos&lt;/b&gt;, a precondição mais fraca, &lt;b&gt;o comando "stored"&lt;/b&gt;, o milagre excluído, e os famosos &lt;b&gt;"semáforos"&lt;/b&gt; para controlar processos de computador. O dicionário inglês de Oxford cita seu uso das palavras "vetor" e "pilha" em um contexto de computação.&lt;br /&gt;
&lt;br /&gt;
Dijkstra apreciava tocar Mozart para seus amigos em seu piano Boesendorfer. Ele e sua esposa tinham um gosto por explorar os parques nacionais em sua caminhonete Volkswagen, chamada a "máquina de Turing", na qual escreveu muitos trabalhos técnicos.&lt;br /&gt;
&lt;br /&gt;
Durante toda sua carreira científica, Dijkstra formulou e perseguiu ideais acadêmicos de mais elevados rigores científicos, desvinculado de&lt;br /&gt;
considerações comerciais ou políticas. &lt;b&gt;Simplicidade, beleza, e eloqüência eram seus pontos fortes&lt;/b&gt;, e sua insistência na elegância na programação e na matemática eram uma inspiração a milhares. Julgou seu próprio trabalho por padrões mais elevados e lançou um desafio a seus muitos amigos para fazerem o mesmo.&lt;br /&gt;
&lt;br /&gt;
Na passagem de Dijkstra, deixe-nos recordar a observação da divisão de Phaedo sobre Sócrates: &lt;b&gt;"nós podemos verdadeiramente dizer que de todos os homens de seu tempo, ele era o mais sábio, o mais justo e o melhor"&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Autor:&lt;/b&gt; Desconhecido&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-8880178324813288954?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/xSmohU2D40o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/8880178324813288954/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/personagens-da-computacao-dijkstra.html#comment-form" title="2 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/8880178324813288954?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/8880178324813288954?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/xSmohU2D40o/personagens-da-computacao-dijkstra.html" title="[Personagens da Computação] Dijkstra, Edsger Wybe" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/personagens-da-computacao-dijkstra.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4DQX04fSp7ImA9WxNWFU4.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-4200559537370083498</id><published>2009-10-14T12:49:00.002-04:00</published><updated>2009-10-14T12:49:30.335-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-14T12:49:30.335-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><category scheme="http://www.blogger.com/atom/ns#" term="implementações" /><title>Algoritmo de Dijkstra</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TNGNp0h6PgPLM1sELPh2FePuSQI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TNGNp0h6PgPLM1sELPh2FePuSQI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TNGNp0h6PgPLM1sELPh2FePuSQI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TNGNp0h6PgPLM1sELPh2FePuSQI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align='justify'&gt;&lt;b&gt;"A arte de programar consiste em organizar e dominar a complexidade" - &lt;i&gt;Edsger W. Dijkstra&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Este artigo discute um algoritmo eficiente para o Problema de Caminho de Custo Mínimo a partir de uma origem:&lt;br /&gt;
&lt;br /&gt;
Dado um digrafo com custos não-negativos nos arcos e um vértice s, encontrar um caminho de custo mínimo com raiz s no digrafo.&lt;br /&gt;
O algoritmo foi inventado por Dijkstra [pronuncie algo entre "Dêcstra" e "Dêicstra"] e publicado em 1959. O algoritmo pode ser usado, em particular, para encontrar um caminho de custo mínimo de um dado vértice a outro.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;O algoritmo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A estrutura do algoritmo de Dijkstra é muito parecida com a do algoritmo de Prim. (Embora o algoritmo de Dijkstra, ao contrário do algoritmo de Prim, &lt;b&gt;só se aplique a custos não-negativos&lt;/b&gt;.)&lt;br /&gt;
&lt;br /&gt;
No início de cada iteração, temos uma arborescência T com raiz s. Para qualquer vértice w fora de T, o custo de w em relação a T é, por definição,&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;a distância de s a w no digrafo T+F,&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
sendo F a franja de T. Aqui, a franja de T é o conjunto de todos os arcos que saem de T. Em outras palavras, o custo de um vértice w que está fora de T é o custo de um caminho mínimo dentre os que começam em s, terminam em w, e só têm um arco — o último — fora de T.  Diremos que o último arco de um tal caminho mínimo é o arco-pai de w. &lt;br /&gt;
&lt;br /&gt;
Cada iteração do algoritmo de Dijkstra consiste no seguinte:&lt;br /&gt;
&lt;br /&gt;
1. &lt;b&gt;se&lt;/b&gt; a franja de T não é vazia&lt;br /&gt;
1.1 &lt;b&gt;então&lt;/b&gt; seja  w  um vértice fora de T que tem custo mínimo&lt;br /&gt;
1.2 seja &lt;i&gt;e&lt;/i&gt; o arco-pai de w&lt;br /&gt;
1.3 comece nova iteração com  T+e  no papel de T&lt;br /&gt;
2. &lt;b&gt;senão&lt;/b&gt; pare&lt;br /&gt;
&lt;br /&gt;
Nas implementações abaixo, a arborescência T será representada por um vetor pai. O custo de cada vértice w será armazenado em &lt;b&gt;cst[w]&lt;/b&gt; e a ponta inicial do arco-pai de w será armazenada em &lt;b&gt;fr[w]&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
As implementações que examinaremos abaixo têm uma peculiaridade: no início da primeira iteração, a árvore (representada pelo vetor pai) está vazia. Somente a partir do início da segunda iteração a implementação passa a se comportar de acordo com o algoritmo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Implementação para digrafos densos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Suponha que nosso digrafo está representado por sua matriz de adjacência. Como de hábito, se v-w não é arco então G[v][w] vale maxCST.  Supõe-se que o valor de maxCST é tão grande que não se confunde com o custo de um caminho simples.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class='cpp' name='code'&gt;/* Recebe digrafo G com custos não-negativos nos arcos e um vértice s. Calcula uma arborescência de caminhos mínimos com raiz s. A arborescência é armazenada no vetor pai. As distâncias em relação a s são armazenadas no vetor cst. */

/* A função supõe que a soma dos custos de todas os arcos é estritamente menor que maxCST.  Supõe também que o digrafo tem no máximo maxV vértices. */

void dijkstraV1(int s) { 
   int w, w0, fr[maxV];
   for (w = 0; w &lt; n; w++) { 
      pai[w] = -1; 
      cst[w] = maxCST; 
   }
   fr[s] = s;
   cst[s] = 0.0;
   while (1) {
      double mincst = maxCST;
      for (w = 0; w &lt; n; w++) {
         if (pai[w] == -1 &amp;&amp; mincst &gt; cst[w])
               mincst = cst[w0=w]; 
      if (mincst == maxCST) break;
      pai[w0] = fr[w0];
      for (w = 0; w &lt; n; w++) 
         if (cst[w] &gt; cst[w0] + G[w0][w]) {
            cst[w] = cst[w0] + G[w0][w]; 
            fr[w] = w0; 
         }
   }
}
&lt;/pre&gt;Note que essa implementação é quase idêntica à implementação correspondente do algoritmo de Prim.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Duas observações técnicas:&lt;/b&gt;  &lt;br /&gt;
1. Observe como a comparação de cst[w] com cst[w0] + G[w0][w] trata corretamente do caso em que w0 e w não são adjacentes e portanto G[w0][w] vale maxCST.  &lt;br /&gt;
2. Estamos supondo, implicitamente, que maxCST é menor que a metade de DBL_MAX, de modo que a expressão cst[w0] + G[w0][w] não produz overflow.&lt;br /&gt;
&lt;br /&gt;
No começo de cada iteração (a partir da segunda) temos uma arborescência com raiz s, representada pelo vetor pai.  No início de cada iteração, as seguinte propriedades valem para cada vértice v:&lt;br /&gt;
&lt;br /&gt;
1. &lt;b&gt;se&lt;/b&gt; v está na arborescência então cst[v] é a distância de s a v,&lt;br /&gt;
&lt;b&gt;senão&lt;/b&gt;, cst[v] é o custo do vértice v em relação à arborescência;&lt;br /&gt;
&lt;br /&gt;
2. &lt;b&gt;se&lt;/b&gt; v está fora da arborescência e cst[v] &lt; maxCST &lt;b&gt;então&lt;/b&gt;&lt;br /&gt;
fr[v] é o penúltimo vértice de um caminho simples de custo cst[v] que liga s a v.&lt;br /&gt;
&lt;br /&gt;
A operação mais característica do algoritmo de Dijkstra é a &lt;b&gt;relaxação de um arco&lt;/b&gt;:&lt;br /&gt;
&lt;pre class='cpp' name='code'&gt;         if (cst[w] &gt; cst[w0] + G[w0][w]) {
             cst[w] = cst[w0] + G[w0][w]; 
         }
&lt;/pre&gt;Essa operação aparece em toda implementação do algoritmo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Implementação para digrafos esparsos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A implementação para digrafos representados por vetor de &lt;b&gt;listas de adjacência usa uma fila de prioridades&lt;/b&gt;, tal como a correspondente implementação do algoritmo de Prim.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class='cpp' name='code'&gt;/* Recebe digrafo G com custos não-negativos nos arcos e um vértice s. Calcula uma SPT com origem s. A SPT é armazenada no vetor pai. As distâncias em relação a s são armazenadas no vetor cst. */

/* A implementação supõe que a soma dos custos de todos os arcos é estritamente menor que maxCST.  Supõe também que o digrafo tem no máximo maxV vértices. */

void dijkstraEsparso (int s) { 
   int w, w0, fr[maxV], p;
   PQinit(); 
   for (w = 0; w &lt; n; w++) 
      pai[w] = fr[w] = -1; 
   fr[s] = s; 
   cst[s] = 0.0; 
   PQinsert(s);
   while (!PQempty()) {
      w0 = PQdelmin(); 
      pai[w0] = fr[w0]; 
      for (p = 0; p &lt; grau[w0]; p++) {
         w = G[w0][p].w;
         if (fr[w] == -1) { 
            cst[w] = cst[w0] + G[w0][p].cst; 
            PQinsert(w); 
            fr[w] = w0; 
         } 
         else if (cst[w] &gt; cst[w0] + G[w0][p].cst) {
            cst[w] = cst[w0] + G[w0][p].cst; 
            PQdec(w); 
            fr[w] = w0; 
         }
      }
   }
}
&lt;/pre&gt;(Note a operação de relaxação  if (cst[w] &gt; cst[w0]+G[w0][p].cst) { cst[w] = cst[w0]+G[w0][p].cst; }  característica do algoritmo de Dijkstra.)&lt;br /&gt;
&lt;br /&gt;
A função dijkstraEsparso usa uma fila de vértices com prioridades definidas pelo vetor cst. A fila é manipulada pelas seguintes funções:&lt;br /&gt;
&lt;br /&gt;
PQinit():  inicializa uma fila de vértices em que todo vértice v tem prioridade cst[v].&lt;br /&gt;
PQempty():  devolve 1 se a fila estiver vazia e 0 em caso contrário.&lt;br /&gt;
PQinsert(v):  insere o vértice v na fila.&lt;br /&gt;
PQdelmin():  retira da fila um vértice de prioridade mínima.&lt;br /&gt;
PQdec(v):  reorganiza a fila depois que o valor de cst[v] foi decrementado.&lt;br /&gt;
A implementação clássica da fila de prioridades usa uma estrutura de heap.&lt;br /&gt;
&lt;br /&gt;
Tal como fizemos com o algoritmo de Prim, podemos organizar a implementação do algoritmo de Dijkstra de maneira um pouco diferente, inserindo todos os vértices na fila de prioridades antes mesmo do início do processo iterativo:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class='cpp' name='code'&gt;void dijkstraV2 (int s) { 
   int w, w0, p;
   PQinit(); 
   for (w = 0; w &lt; n; w++) { 
      pai[w] = -1; 
      cst[w] = maxCST; 
      PQinsert(w); 
   }
   pai[s] = s;
   cst[s] = 0.0; 
   PQdec(s);
   while (!PQempty()) {
      w0 = PQdelmin();
      if (cst[w0] == maxCST) break;
      for (p = 0; p &lt; grau[w0]; p++) {
         w = p-&gt;w;
         if (cst[w] &gt; cst[w0] + G[w0][p].cst) { 
            cst[w] = cst[w0] + G[w0][p].cst; 
            PQdec(w); 
            pai[w] = w0; 
         }
      }
   }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Fonte:&lt;/b&gt; &lt;a href='http://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/dijkstra.html' target='_blank'&gt;IME&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-4200559537370083498?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/EQuSCH9DyrI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/4200559537370083498/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/algoritmo-de-dijkstra.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4200559537370083498?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4200559537370083498?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/EQuSCH9DyrI/algoritmo-de-dijkstra.html" title="Algoritmo de Dijkstra" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/algoritmo-de-dijkstra.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQDR34ycSp7ImA9WxNWFEo.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-103066251304935429</id><published>2009-10-13T17:46:00.000-04:00</published><updated>2009-10-13T17:46:16.099-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-13T17:46:16.099-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><title>Caminhos de custo mínimo</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/H3Eo2UqZd0ASzX36nbawSf8MGMY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/H3Eo2UqZd0ASzX36nbawSf8MGMY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/H3Eo2UqZd0ASzX36nbawSf8MGMY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/H3Eo2UqZd0ASzX36nbawSf8MGMY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align='justify'&gt;Este artigo introduz o problema dos caminhos de custo mínimo em digrafos com custos nos arcos.  Vamos supor que todos os custos são não-negativos (o problema faz sentido sem essa hipótese, mas fica bem mais difícil).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Caminhos mínimos e distâncias&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Num digrafo com custos nos arcos, o custo de um caminho é a soma dos custos dos arcos do caminho. &lt;b&gt;Um caminho C é mínimo se não existe outro caminho com mesma origem e mesmo término que C, mas mais barato que C&lt;/b&gt;. Por causa da presença dos custos, este conceito é mais geral que o conceito de caminho mínimo definido em outro artigo.&lt;br /&gt;
&lt;br /&gt;
A distância de um vértice s a um vértice t é o custo de um caminho mínimo de s a t. Em outras palavras, a distância de s a t é d se e somente se  &lt;br /&gt;
(1) existe um caminho de custo d de s a t; e  &lt;br /&gt;
(2) nenhum caminho de s a t tem custo menor que d.&lt;br /&gt;
&lt;br /&gt;
Se o digrafo é um grafo, a distância de s a t é igual à distância de t a s. Portanto, podemos usar a expressão "distância entre s e t" nesse caso.&lt;br /&gt;
&lt;br /&gt;
Vamos supor, ao tratar de caminhos mínimos e distâncias, que o custo de cada arco &lt;b&gt;é um número não-negativo&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Assim, a distância de um vértice s a um vértice t fica bem definida sempre que existe algum caminho de s a t.  (Se não existe caminho algum, podemos dizer que a distância de s a t é infinita.)   [O problema do caminho mínimo em digrafos que têm arcos de custo negativo é muito importante, mas bem mais difícil. No caso de digrafos simétricos, ele está relacionado com o célebre problema do caminho hamiltoniano.]&lt;br /&gt;
&lt;br /&gt;
Digrafos com custos não-negativos têm a seguinte propriedade crucial: &lt;b&gt;qualquer segmento de um caminho mínimo é um caminho mínimo&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Outro aspecto dessa mesma propriedade: a menos que o digrafo tenha um ciclo de custo nulo, todo caminho mínimo é simples. Mesmo que o digrafo tenha ciclos de custo nulo, é verdade que para todo vértice s e todo vértice t&lt;br /&gt;
&lt;br /&gt;
existe um caminho simples de s a t cujo custo é igual à distância de s a t&lt;br /&gt;
&lt;br /&gt;
(desde que essa distância seja finita). Podemos nos restringir, portanto, a caminho mínimos que são simples.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;O problema do caminho mínimo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Nosso problema básico é o seguinte: &lt;br /&gt;
&lt;br /&gt;
Problema do Caminho Mínimo com Origem e Término Fixos (Source-sink Shortest Path Problem):  Dados vértices s e t de um digrafo com custos não-negativos nos arcos, encontrar um caminho mínimo simples de s a t.&lt;br /&gt;
(É claro que o problema só tem solução se t pode ser alcançado a partir de s, ou seja, se existe um caminho de s a t.)  &lt;br /&gt;
&lt;br /&gt;
A experiência mostra que é &lt;b&gt;mais prático tratar de um problema mais geral&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
Problema dos Caminhos Mínimos com Origem Fixa (Single-source Shortest Paths Problem):  Dado um vértice s de um digrafo com custos não-negativos nos arcos, encontrar, para cada vértice t que pode ser alcançado a partir de s, um caminho mínimo simples de s a t.&lt;br /&gt;
&lt;br /&gt;
Todos os algoritmos para esses problemas exploram a seguinte propriedade básica:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Propriedade Triangular&lt;/b&gt;:  Para quaisquer vértices x, y e z de um digrafo com custos não-negativos nos arcos, tem-se&lt;br /&gt;
&lt;b&gt;d(x,z)  ≤  d(x,y) + d(y,z) ,&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
sendo d(i,j) a distância de i a j.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Arborescência de caminhos mínimos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Dado um vértice s de um digrafo G com custos não-negativos nos arcos, uma arborescência de caminhos mínimos (= shortest-paths tree = SPT) com raiz s é uma arborescência em G que tem a seguinte propriedade:  para todo vértice t de G que pode ser alcançado a partir de s,&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;o único caminho de s a t na arborescência é um caminho mínimo em G.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Vou usar a sigla em inglês — SPT — para me referir a uma arborescência de caminhos mínimos. É claro que qualquer SPT pode ser representada por um vetores de pais.&lt;br /&gt;
&lt;br /&gt;
Uma SPT pode ser vista como uma solução do Problema dos Caminhos Mínimos Com Origem Fixa.  Por isso mesmo, esse problema pode ser reformulado assim:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Problema da SPT&lt;/b&gt;:  Dado um vértice s de um digrafo com custos não-negativos nos arcos, encontrar uma SPT com raiz s no digrafo.&lt;br /&gt;
Exemplo&lt;br /&gt;
&lt;br /&gt;
A tabela define um digrafo com custos nos arcos.&lt;br /&gt;
&lt;br /&gt;
0-1 .41&lt;br /&gt;
1-2 .51&lt;br /&gt;
2-3 .50&lt;br /&gt;
4-3 .36&lt;br /&gt;
3-5 .38&lt;br /&gt;
3-0 .45&lt;br /&gt;
0-5 .29&lt;br /&gt;
5-4 .21&lt;br /&gt;
1-4 .32&lt;br /&gt;
4-2 .32&lt;br /&gt;
5-1 .29&lt;br /&gt;
A tabela abaixo dá a distância de 0 a cada um dos demais vértices. Também especifica caminhos mínimos de 0 a cada um dos demais vértices.&lt;br /&gt;
&lt;br /&gt;
0  .0     0      &lt;br /&gt;
1  .41    0-1    &lt;br /&gt;
2  .82    0-5-4-2&lt;br /&gt;
3  .86    0-5-4-3&lt;br /&gt;
4  .50    0-5-4  &lt;br /&gt;
5  .29    0-5    &lt;br /&gt;
Eis uma SPT com origem 0 representados por um vetores de pais:&lt;br /&gt;
&lt;br /&gt;
      v     0  1  2  3  4  5&lt;br /&gt;
pai[v]    0  0  4  4  5  0&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fonte:&lt;/b&gt; &lt;a href='http://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/cheapestpaths.html' target='_blank'&gt;IME&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-103066251304935429?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/tMc2gqFUfPw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/103066251304935429/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/caminhos-de-custo-minimo.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/103066251304935429?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/103066251304935429?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/tMc2gqFUfPw/caminhos-de-custo-minimo.html" title="Caminhos de custo mínimo" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/caminhos-de-custo-minimo.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8EQ306eip7ImA9WxNWFEs.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-2805369957166620299</id><published>2009-10-13T15:36:00.002-04:00</published><updated>2009-10-13T15:40:02.312-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-13T15:40:02.312-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><category scheme="http://www.blogger.com/atom/ns#" term="implementações" /><title>Algoritmo de Prim</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/z5IPZOdyVL4FbB1HPIxUWPBBEaE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/z5IPZOdyVL4FbB1HPIxUWPBBEaE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/z5IPZOdyVL4FbB1HPIxUWPBBEaE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/z5IPZOdyVL4FbB1HPIxUWPBBEaE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align='justify'&gt;Nosso problema neste artigo é o mesmo do anterior: encontrar uma MST (árvore geradora mínima) de um grafo G com custos nas arestas.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;O algoritmo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
O algoritmo de Prim (publicado em 1961) se apoia nas condições de otimalidade de MSTs para encontrar uma MST de um grafo G com custos nas arestas.&lt;br /&gt;
&lt;br /&gt;
Para descrever o algoritmo, convém recorrer ao conceito de franja. A &lt;b&gt;franja&lt;/b&gt; (= fringe) de uma subárvore não-geradora T de G é o conjunto de todas as arestas de G que têm uma ponta em T e outra ponta fora. Se denotarmos por X o conjunto dos vértices de T e por Y o conjunto dos vértices fora de X, podemos dizer que a franja é o conjunto das arestas que pertencem ao &lt;a href='http://javafree.uol.com.br/artigo/874963/GRAFOS-Conexao-digrafos-conexos.html'&gt;corte&lt;/a&gt; (X,Y).&lt;br /&gt;
&lt;br /&gt;
No início de cada iteração do algoritmo de Prim temos uma árvore T.  (No início da primeira iteração, T consiste em um único vértice.)  Cada iteração consiste no seguinte:&lt;br /&gt;
&lt;br /&gt;
1. &lt;b&gt;se&lt;/b&gt; a franja de T não é vazia&lt;br /&gt;
1.1 &lt;b&gt;então&lt;/b&gt;  seja e uma aresta de custo mínimo na franja&lt;br /&gt;
1.2 comece nova iteração com  T+e  no papel de T&lt;br /&gt;
2. &lt;b&gt;senão&lt;/b&gt; pare&lt;br /&gt;
&lt;br /&gt;
Se G for conexo, o algoritmo produz uma MST de G. Caso contrário, o algoritmo produz uma MST de uma das &lt;a href='http://javafree.uol.com.br/artigo/874867/GRAFOS-Componentes-de-grafos.html'&gt;componentes&lt;/a&gt; de G.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Implementação grosseira do algoritmo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Nossa primeira implementação do algoritmo de Prim é simples e óbvia mas ineficiente. A função abaixo recebe um grafo G com custos nas arestas e calcula uma MST da componente de G que contém o vértice 0.  A MST é tratada como uma arborescência com raiz 0 e armazenada no vetor de pais &lt;i&gt;pai&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
A função supõe que o grafo é representado por sua &lt;b&gt;matriz de adjacência&lt;/b&gt; e o &lt;b&gt;custo&lt;/b&gt; de cada aresta é estritamente menor que &lt;b&gt;maxCST&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class='cpp' name='code'&gt;void primForcaBruta() { 
   int v, w; 
   for (w = 0; w &lt; n; w++) pai[w] = -1; 
   pai[0] = 0; 
   while (1) {
      double mincst = maxCST;
      int v0, w0;
      for (w = 0; w &lt; n; w++) 
         if (pai[w] == -1) 
            for (v = 0; v &lt; n; v++)
               if (pai[v] != -1 &amp;&amp; mincst &gt; G[v][w]) 
                  mincst = G[v0=v][w0=w];
      if (mincst == maxCST) break; 
      /* A */
      pai[w0] = v0;
   }
}
&lt;/pre&gt;No ponto A, &lt;b&gt;v0-w0 é uma aresta de custo mínimo&lt;/b&gt; dentre as que estão na franja da árvore. O custo da aresta v0-w0 é mincst.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Implementações eficientes&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Toda implementação eficiente do algoritmo de Prim &lt;b&gt;depende do conceito de custo de um vértice em relação a uma árvore&lt;/b&gt;. Dada uma árvore não-geradora do grafo, o custo de um vértice w que está fora da árvore é o custo de uma aresta mínima dentre as que incidem em w e estão na franja da árvore. Em outras palavras, o custo de w é o custo de uma aresta mínima dentre as que têm uma ponta na árvore e outra em w.  Se nenhuma aresta da franja incide em w, o custo de w é maxCST (que é maior que o custo de qualquer aresta e portanto tem o sabor de ∞).&lt;br /&gt;
&lt;br /&gt;
Nas implementações que examinaremos abaixo, os custos dos vértices e as arestas que justificam esses custos são representados pelos vetores&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;cst e fr&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
O custo do vértice w em relação à árvore é cst[w]. Para cada vértice w fora da árvore, o vértice fr[w] está na árvore e a aresta que liga w a fr[w] tem custo cst[w]. Cada iteração do algoritmo de Prim escolhe um vértice w fora da árvore e adota fr[w] como valor de pai[w].&lt;br /&gt;
&lt;br /&gt;
As implementações que examinaremos abaixo têm uma peculiaridade: no início da primeira iteração, a árvore (representada pelo vetor pai) está vazia. Durante a primeira iteração a árvore adquire seu primeiro vértice e a partir da segunda iteração a implementação passa a se comportar como o algoritmo descrito acima.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Implementação eficiente para grafos densos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A implementação abaixo é ótima para grafos densos. É apropriado, portanto, representar o grafo por uma matriz de adjacência:&lt;br /&gt;
&lt;br /&gt;
/* Recebe grafo G com custos nas arestas e calcula uma MST da componente de G que contém o vértice 0.  A função armazena a MST no vetor pai, tratando-a como uma arborescência com raiz 0. */&lt;br /&gt;
&lt;br /&gt;
/* O grafo G é representado por sua matriz de adjacência. A função supõe que e.cst &lt; maxCST para cada aresta e.  Supõe também que o grafo tem no máximo maxV vértices. */

&lt;pre class='cpp' name='code'&gt;&lt;br /&gt;
void primDenso() { &lt;br /&gt;
double cst[maxV]; &lt;br /&gt;
int v0, w, fr[maxV];&lt;br /&gt;
for (w = 0; w &lt; n; w++) {
      pai[w] = -1; 
      cst[w] = maxCST; 
   }
   v0 = 0;
   fr[v0] = v0;
   cst[v0] = 0.0;
   while (1) {
      double mincst = maxCST; 
      for (w = 0; w &lt; n; w++) 
         if (pai[w] == -1 &amp;&amp; mincst &gt; cst[w]) &lt;br /&gt;
mincst = cst[v0=w]; &lt;br /&gt;
if (mincst == maxCST) break;&lt;br /&gt;
pai[v0] = fr[v0];&lt;br /&gt;
for (w = 0; w &lt; n; w++) 
         if (pai[w] == -1 &amp;&amp; cst[w] &gt; G[v0][w]) {&lt;br /&gt;
cst[w] = G[v0][w]; &lt;br /&gt;
fr[w] = v0; &lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
O fragmento de código&lt;br /&gt;
&lt;pre class='cpp' name='code'&gt;if (cst[w] &gt; G[v0][w]) {
                cst[w] = G[v0][w]; 
            }
&lt;/pre&gt;é característico do algoritmo de Prim. A operação que ele executa é conhecida como relaxação (da aresta v0-w).  Essa operação aparece em toda implementação do algoritmo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Desempenho&lt;/b&gt;: No pior caso, o consumo tempo da função primDenso é proporcional a &lt;b&gt;V^2&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Portanto, a função primDenso é linear para grafos densos (pois o tamanho de tais grafos é proporcional a V^2).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Implementação eficiente para grafos esparsos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Esta seção discute uma implementação mais sofisticada do algoritmo de Prim. Ela usa uma fila de prioridades (= priority queue) para escolher, eficientemente, a próxima aresta a ser acrescentada à árvore. &lt;br /&gt;
&lt;br /&gt;
&lt;pre class='cpp' name='code'&gt;static double cst[maxV];
/* Recebe grafo G com custos nas arestas e calcula uma MST da componente de G que contém o vértice 0.  A função armazena a MST no vetor pai, tratando-a como uma arborescência com raiz 0. */

/* O grafo G é representado por listas de adjacência. */

void primEsparso() { 
   int v0, w, fr[maxV], p; 
   PQinit(); 
   for (w = 0; w &lt; n; w++) 
      pai[w] = fr[w] = -1; 
   v0 = 0;
   fr[v0] = v0; 
   cst[v0] = 0.0; 
   PQinsert(v0);
   while (!PQempty()) {
      v0 = PQdelmin(); 
      pai[v0] = fr[v0]; 
      for (p = 0; p &lt; grau[v0]; p++) {
         w = g[v0][p].w;
         if (pai[w] == -1) {
            if (fr[w] == -1) { 
               cst[w] = g[v0][p].cst; 
               PQinsert(w); 
               fr[w] = v0; 
            } 
            else if (cst[w] &gt; g[v0][p].cst) {
               cst[w] = g[v0][p].cst; 
               PQdec(w); 
               fr[w] = v0; 
            }
         }
      }
   }
}
&lt;/pre&gt;(Note a operação de relaxação  if (cst[w] &gt; g[v0][p].cst) { cst[w] = g[v0][p].cst; }  característica do algoritmo de Prim.)&lt;br /&gt;
&lt;br /&gt;
A função primEsparso usa uma fila com prioridades. A fila é manipulada pelas seguintes funções:&lt;br /&gt;
&lt;br /&gt;
PQinit():  inicializa uma fila de vértices em que cada vértice v tem prioridade cst[v].&lt;br /&gt;
PQempty():  devolve 1 se a fila estiver vazia e 0 em caso contrário.&lt;br /&gt;
PQinsert(v):  insere o vértice v na fila.&lt;br /&gt;
PQdelmin():  retira da fila um vértice de prioridade mínima.&lt;br /&gt;
PQdec(w):  reorganiza a fila depois que o valor de cst[w] foi decrementado.&lt;br /&gt;
&lt;br /&gt;
A implementação clássica da fila de prioridades usa uma estrutura de heap. O heap é armazenado num vetor &lt;b&gt;pq[1..N]&lt;/b&gt; (a posição 0 do vetor não é usada). A prioridade de um vértice pq[k] no heap é cst[pq[k]]. &lt;b&gt;Propriedade fundamental do heap:  &lt;br /&gt;
&lt;br /&gt;
cst[pq[k/2]] ≤ cst[pq[k]]&lt;br /&gt;
&lt;br /&gt;
para k=2,..,N.  Portanto, o vértice pq[1] minimiza cst&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class='cpp' name='code'&gt;/*Supõe-se que N ≤ maxV. */

/* O vetor qp é o "inverso" de pq:  para cada vértice v, qp[v] é o único índice tal que pq[qp[v]] == v.  É claro que qp[pq[i]] == i para todo i. */

static Vertex pq[maxV+1]; 
static int N;
static int qp[maxV]; 

void PQinit(void) { 
  N = 0; 
}
int PQempty(void) { 
   return N == 0; 
}
void PQinsert(Vertex v) { 
   qp[v] = ++N; 
   pq[N] = v; 
   fixUp(N); 
}
Vertex PQdelmin(void) { 
   exch(1, N); 
   --N; 
   fixDown(1); 
   return pq[N+1]; 
}
void PQdec(Vertex w) { 
   fixUp(qp[w]); 
}
static void exch(int i, int j) {
   Vertex t;
   t = pq[i]; pq[i] = pq[j]; pq[j] = t;
   qp[pq[i]] = i;
   qp[pq[j]] = j;
}
static void fixUp(int k) {
   while (k &gt; 1 &amp;&amp; cst[pq[k/2]] &gt; cst[pq[k]]) {
      exch(k/2, k);
      k = k/2;
}
static void fixDown(int k) { 
   int j;
   while (2*k &lt;= N) { 
      j = 2*k;
      if (j &lt; N &amp;&amp; cst[pq[j]] &gt; cst[pq[j+1]]) j++;
      if (cst[pq[k]] &lt;= cst[pq[j]]) break;
      exch(k, j); 
      k = j;
   }
}
&lt;/pre&gt;&lt;br/&gt;
(O código de primEsparso pode parecer um pouco assustador porque depende de um grande número de funções auxiliares.  Pode ser um bom exercício escrever uma versão "compacta" da função primEsparso, que incorpore, tanto quanto razoável, o código das funções de manipulação da fila de prioridades.)&lt;br/&gt;

&lt;b&gt;Desempenho:&lt;/b&gt; Eis uma estimativa do consumo de tempo no pior caso de cada uma das funções de manipulação da fila de prioridades quando aplicada a um grafo com V vértices:&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;

PQinit:  constante, ou seja, não depende de V;&lt;br/&gt;
PQempty:  constante, ou seja, não depende de V;&lt;br/&gt;
PQinsert:  proporcional a lg(V);&lt;br/&gt;
PQdelmin:  proporcional a lg(V);&lt;br/&gt;
PQdec:  proporcional a lg(V).&lt;br/&gt;
Assim, o consumo de tempo da função primEsparso é proporcional a  V lg(V) + E lg(V)  no pior caso. Para grafos conexos, essa expressão se reduz a&lt;br/&gt;

&lt;b&gt;E lg(V)&lt;/b&gt;.&lt;br/&gt;
&lt;br/&gt;
Portanto, a função primEsparso é um pouco pior que linear.  Mesmo assim, esse desempenho é melhor que o da função primDenso quando os grafos são esparsos.&lt;br/&gt;

&lt;b&gt;Outra implementação para grafos esparsos&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;

O código abaixo é uma variante da função primEsparso. Nessa variante, os vértices são todos colocados na fila de prioridades antes do início do processo iterativo. O vetor pai usurpa o papel de fr e fr é dispensado. Com isso, o valor de cada elemento de pai pode ser alterados várias vezes ao longo do processo iterativo (ao contrário do que acontece em primEsparso).&lt;br/&gt;&lt;br/&gt;

O código dessa variante é mais curto que o de primEsparso (embora não seja mais eficiente).  Por isso, há quem considere essa variante mais atraente.&lt;br/&gt;&lt;br/&gt;

&lt;pre class='cpp' name='code'&gt;static double cst[maxV];

void primSimples() { 
   int v0, w, p;
   PQinit(); 
   for (w = 0; w &lt; n; w++) { 
      pai[w] = -1;
      cst[w] = maxCST; 
      PQinsert(w); 
   }
   v0 = 0;
   pai[v0] = v0;
   cst[v0] = 0.0; 
   PQdec(v0);
   while (!PQempty()) {
      v0 = PQdelmin();
      if (cst[v0] == maxCST) break;
      for (p = 0; p &lt; grau[v0]; p++) {
         w = g[v0][p].w;
         if (cst[w] &gt; g[v0][p].cst) { 
            cst[w] = g[v0][p].cst; 
            PQdec(w); 
            pai[w] = v0; 
         }
      }
   }
}&lt;/pre&gt;&lt;br/&gt;
&lt;b&gt;Exercícios para Fixação&lt;/b&gt;&lt;br/&gt;
1. Qual a diferença entre grafos esparsos e grafos densos?&lt;br/&gt;
2. Esta afirmação: "A implementação abaixo é ótima para grafos densos. É apropriado, portanto, representar o grafo por uma matriz de adjacência." está correta? Porque?&lt;br/&gt;
3. Qual a vantagem de se saber se o grafo é esparso ou denso quando precisamos saber sua árvore geradora mínima?&lt;br/&gt;
4. Porque usar uma fila de prioridade ao invés de utilizar uma fila comum?&lt;br/&gt;

&lt;b&gt;Fonte:&lt;/b&gt; &lt;a href='http://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/prim.html' target='_blank'&gt;IME&lt;/a&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-2805369957166620299?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/9Qkkh_3gtlY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/2805369957166620299/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/algoritmo-de-prim.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/2805369957166620299?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/2805369957166620299?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/9Qkkh_3gtlY/algoritmo-de-prim.html" title="Algoritmo de Prim" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/algoritmo-de-prim.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAHRn84eip7ImA9WxNWFEk.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-1866920814218877582</id><published>2009-10-13T11:28:00.002-04:00</published><updated>2009-10-13T11:28:57.132-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-13T11:28:57.132-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><title>Árvores geradoras de custo mínimo - MST</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yv5rehjOu2jkQxBgOe4KyjXub6o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yv5rehjOu2jkQxBgOe4KyjXub6o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yv5rehjOu2jkQxBgOe4KyjXub6o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yv5rehjOu2jkQxBgOe4KyjXub6o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align='justify'&gt;Iremos introduzir alguns conceitos ao decorrer deste artigo até chegarmos a árvore geradora mínima em si. E também iremos falar de algumas de suas propriedades.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Subgrafo de custo mínimo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Seja G um grafo com &lt;b&gt;custos nas arestas&lt;/b&gt; (os custos podem ser positivos, negativos, ou nulos). O custo de um subgrafo T de G é a soma dos custos das arestas de T. Se U é uma coleção de subgrafos de G, um elemento T de U tem custo mínimo se o custo de T é menor ou igual [note o "ou igual"] que o custo de qualquer outro elemento de U.&lt;br /&gt;
&lt;br /&gt;
Em outras palavras, &lt;b&gt;T tem custo mínimo se nenhum&lt;/b&gt; elemento de U tem custo estritamente &lt;b&gt;menor que o de T&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Árvore geradora mínima&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Uma árvore geradora mínima (= minimum spanning tree), ou MST, de um grafo com custos nas arestas é qualquer árvore geradora do grafo que tenha custo mínimo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Problema:&lt;/b&gt; Encontrar uma MST de um grafo G com custos nas arestas.&lt;br /&gt;
&lt;br /&gt;
É claro que o problema tem solução se e somente se o grafo G é conexo. Boa pergunta: como encontrar uma MST de um grafo conexo se todas as suas arestas têm o mesmo custo?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A propriedade dos ciclos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A Primeira Propriedade da Troca, discutida no artigo anterior, leva à seguinte condição de otimalidade:&lt;br /&gt;
&lt;br /&gt;
Condição de Otimalidade: Se T é uma MST de um grafo então toda aresta e fora de T tem custo máximo dentre as arestas do único ciclo não-trivial em T+e.&lt;br /&gt;
(A recíproca dessa proposição é verdadeira, mas sua demonstração é um pouco mais complexa.)&lt;br /&gt;
&lt;br /&gt;
Exemplo: Seja T a árvore geradora definida pelas 5 arestas "internas" da figura. Seja e a aresta "horizontal" "superior". Como e não é máxima no ciclo não-trivial de T+e, a árvore T não é uma MST.&lt;br /&gt;
&lt;br /&gt;
&lt;img src='http://i722.photobucket.com/albums/ww221/allgoritmos/g2-1.jpg'/&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A propriedade dos cortes&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A Segunda Propriedade da Troca, discutida no artigo anterior, leva à seguinte condição de otimalidade:&lt;br /&gt;
&lt;br /&gt;
Condição de Otimalidade: Se T é uma MST de um grafo então cada aresta t de T é uma aresta mínima dentre as que atravessam o corte determinado por T–t.&lt;br /&gt;
(A recíproca dessa proposição é verdadeira, mas sua demonstração é um pouco mais complexa.)&lt;br /&gt;
&lt;br /&gt;
Exemplo: Seja T a árvore geradora definida pelas cinco arestas "internas" da figura. Seja t a aresta "horizontal" no meio da figura. Como t não é mínima no corte determinado por T–t, a árvore T não é uma MST.&lt;br /&gt;
&lt;img src='http://i722.photobucket.com/albums/ww221/allgoritmos/g2-1.jpg'/&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fonte:&lt;/b&gt; &lt;a href='http://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/mst.html' target='_blank'&gt;IME&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-1866920814218877582?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/IspCKfgl6tI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/1866920814218877582/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/arvores-geradoras-de-custo-minimo-mst.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/1866920814218877582?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/1866920814218877582?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/IspCKfgl6tI/arvores-geradoras-de-custo-minimo-mst.html" title="Árvores geradoras de custo mínimo - MST" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/arvores-geradoras-de-custo-minimo-mst.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcFQXk-cSp7ImA9WxNXGEk.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-4795933060212293354</id><published>2009-10-06T12:20:00.000-04:00</published><updated>2009-10-06T12:20:10.759-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T12:20:10.759-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="novidades" /><category scheme="http://www.blogger.com/atom/ns#" term="notícias" /><title>Trocando a senha do Gmail</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6Q-tUbA6P1f3k_3qJYiF0wCakvA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6Q-tUbA6P1f3k_3qJYiF0wCakvA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6Q-tUbA6P1f3k_3qJYiF0wCakvA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6Q-tUbA6P1f3k_3qJYiF0wCakvA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;Como trocar sua senha do &lt;b&gt;Gmail&lt;/b&gt; ?&lt;br /&gt;
&lt;br /&gt;
Siga os passos:&lt;br /&gt;
&lt;br /&gt;
1. Entre no site do &lt;a href="http://www.gmail.com/"&gt;&lt;b&gt;Gmail&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
2. No menu superior direito clique em &lt;b&gt;CONFIGURAÇÕES.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
3. Depois clique em &lt;b&gt;CONTAS E IMPORTAÇÃO&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
4. Depois lá embaixo clique em &lt;b&gt;CONFIGURAÇÕES DA CONTA GOOGLE&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
5. Agora você verá suas informações e clique em &lt;b&gt;ALTERAR SENHA.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
6. Agora insira sua &lt;b&gt;senha antiga&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
7. Agora insira sua &lt;b&gt;senha nova duas vezes.&lt;br /&gt;
&lt;br /&gt;
&lt;/b&gt;8. Clique em &lt;b&gt;Salvar.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Pronto, sua senha atualizada! &lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-4795933060212293354?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/BpjClF0UBMc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/4795933060212293354/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/trocando-senha-do-gmail.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4795933060212293354?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4795933060212293354?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/BpjClF0UBMc/trocando-senha-do-gmail.html" title="Trocando a senha do Gmail" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/trocando-senha-do-gmail.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AARnwyfyp7ImA9WxNXGEk.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-4085214309680595742</id><published>2009-10-06T12:14:00.001-04:00</published><updated>2009-10-06T12:15:47.297-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T12:15:47.297-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="novidades" /><category scheme="http://www.blogger.com/atom/ns#" term="notícias" /><title>Trocando a senha do Hotmail</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/acBeghJZHvVHthYLpYy11kZWSaI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/acBeghJZHvVHthYLpYy11kZWSaI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/acBeghJZHvVHthYLpYy11kZWSaI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/acBeghJZHvVHthYLpYy11kZWSaI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;Como trocar sua senha do Hotmail ?&lt;br /&gt;
&lt;br /&gt;
Siga os passos:&lt;br /&gt;
&lt;br /&gt;
1. Entre no site do &lt;a href="http://www.hotmail.com/"&gt;HOTMAIL&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
2. No menu superior direito clique em &lt;b&gt;OPÇÕES&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
3. Depois clique em &lt;b&gt;MAIS OPÇÕES&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
4. Depois clique em &lt;b&gt;Exibir e editar suas informações pessoais.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
5. Agora você verá suas informações e clique em &lt;b&gt;ALTERAR&lt;/b&gt; (ao lado de senha *******).&lt;br /&gt;
&lt;br /&gt;
6. Agora insira sua senha &lt;b&gt;antiga&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
7. Agora insira sua senha &lt;b&gt;nova&lt;/b&gt; duas vezes.&lt;br /&gt;
&lt;br /&gt;
8. Clique em &lt;b&gt;Salvar&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Pronto, sua senha &lt;b&gt;atualizada!&lt;/b&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-4085214309680595742?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/qSQ8VU9niNI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/4085214309680595742/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/trocando-senha-do-hotmail.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4085214309680595742?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4085214309680595742?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/qSQ8VU9niNI/trocando-senha-do-hotmail.html" title="Trocando a senha do Hotmail" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/trocando-senha-do-hotmail.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIESXozeip7ImA9WxNXGEk.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-2754066936539704476</id><published>2009-10-06T10:53:00.004-04:00</published><updated>2009-10-06T13:01:48.482-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-06T13:01:48.482-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="notícias" /><title>Senhas Roubadas do Gmail, Hotmail e Yahoo</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ilb7ud04a_tug0Nx_EpYjPVkYvw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ilb7ud04a_tug0Nx_EpYjPVkYvw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ilb7ud04a_tug0Nx_EpYjPVkYvw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ilb7ud04a_tug0Nx_EpYjPVkYvw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;Grupo de Hackers roubou &lt;b&gt;logins e senhas de mais de 20.000 usuários da Google, Yahoo e Hotmail.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
O canal de tv BBC em seu noticiário nesta terça-feira (06/10) recomendou aos seus telespectadores que troquem suas senhas pois os logins e senhas foram divulgadas na internet por alguns instantes e os hackers continuam em posse das mesmas. E estima-se que eles tenham roubado mais de 20.000 pois estes eram somente os iniciados em A ou B.&lt;br /&gt;
&lt;br /&gt;
Então o &lt;b&gt;ALLgoritmos.com&lt;/b&gt; também alerta sobre esse fato e pede que seus leitores alterem suas senhas para que não sejam lesados por essa invasão.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;APRENDA&lt;/b&gt; a trocar sua senha do &lt;b&gt;&lt;a href="http://www.allgoritmos.com/2009/10/trocando-senha-do-gmail.html"&gt;GMAIL&lt;/a&gt;&lt;/b&gt; ou do &lt;b&gt;&lt;a href="http://www.allgoritmos.com/2009/10/trocando-senha-do-hotmail.html"&gt;HOTMAIL&lt;/a&gt;&lt;/b&gt;!&lt;br /&gt;
Clique acima no e-mail que voce usa e aprenda agora como trocar sua senha.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dicas para criação de senha: &lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
- Não utilize seu nome;&lt;br /&gt;
- Não use datas;&lt;br /&gt;
- Não use coisas muito lógicas (como o nome do seu filho/cachorro/mãe);&lt;br /&gt;
&lt;br /&gt;
- Use caracteres normais e especiais;&lt;br /&gt;
- Use senhas aleatórias;&lt;br /&gt;
- Use pelo menos 8 caracteres;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Um bom jeito de criar uma senha:&lt;/b&gt;&lt;br /&gt;
- Digite qualquer coisa no teclado (com números e letras), decore e use como senha;&lt;br /&gt;
&lt;br /&gt;
Obs: Para este tipo de invasão ter uma boa senha não ajuda em nada, mas quando alguém quer descobrir sua senha isso dificulta bastante.&lt;br /&gt;
&lt;br /&gt;
Qualquer novidade sobre o caso estarei atualizando neste post.&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-2754066936539704476?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/IDSopIFlqrw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/2754066936539704476/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/senhas-roubadas-do-gmail-hotmail-e.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/2754066936539704476?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/2754066936539704476?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/IDSopIFlqrw/senhas-roubadas-do-gmail-hotmail-e.html" title="Senhas Roubadas do Gmail, Hotmail e Yahoo" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/senhas-roubadas-do-gmail-hotmail-e.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYFQHo-eip7ImA9WxNXF0g.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-4978236279602433723</id><published>2009-10-05T11:19:00.004-04:00</published><updated>2009-10-05T11:21:51.452-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-05T11:21:51.452-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><title>Árvore Geradora em Grafos</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aeSjYCy0j6EU0jvYPxvtxvEx1A8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aeSjYCy0j6EU0jvYPxvtxvEx1A8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aeSjYCy0j6EU0jvYPxvtxvEx1A8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aeSjYCy0j6EU0jvYPxvtxvEx1A8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align='justify'&gt;&lt;b&gt;Árvore geradora&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Uma subárvore de um grafo G é qualquer árvore T que seja subgrafo de G. Em outras palavras, um árvore T é subárvore de G se todo vértice de T é vértice de G e toda aresta de T é aresta de G.&lt;br /&gt;
&lt;br /&gt;
Uma subárvore geradora ou árvore geradora (= spanning tree) de um grafo G é qualquer subárvore de G que contenha todos os vértices de G.&lt;br /&gt;
&lt;br /&gt;
É claro que somente grafos conexos têm árvores geradoras. Reciprocamente, todo grafo conexo tem uma árvore geradora. (Em geral, um grafo conexo tem muitas árvores geradoras diferentes.)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Algoritmos que calculam árvores geradoras&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
É fácil calcular uma árvore geradora de um grafo conexo: a busca em profundidade e a busca em largura fazem isso. Mais precisamente, qualquer das duas buscas calcula uma arborescência que contém um dos arcos de cada aresta de uma árvore geradora do grafo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Primeira propriedade da troca de arestas&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Seja G um grafo e H um subgrafo gerador de G. Para qualquer aresta h de H, vamos denotar por H–h o grafo que se obtém quando h é removida de H. Para qualquer aresta e de G, vamos denotar por H+e o grafo que se obtém quando e é inserida em H.&lt;br /&gt;
&lt;br /&gt;
Primeira Propriedade da Troca: Seja T uma árvore geradora de um grafo G. Para qualquer aresta e de G que não esteja em T, o grafo T + e tem um único ciclo não-trivial. Para qualquer aresta t desse ciclo, o grafo T + e – t é uma árvore geradora de G.&lt;br /&gt;
Exemplo: Seja T a árvore geradora definida pelas cinco arestas "internas" da figura. Seja e a aresta 0-1. O único ciclo não-trivial de T+e é 0-1-5-4-0. Para qualquer aresta t desse ciclo, T+e–t é uma árvore geradora.&lt;br /&gt;
&lt;br /&gt;
&lt;img src='http://i722.photobucket.com/albums/ww221/allgoritmos/g1-1.png'/&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Segunda propriedade da troca de arestas&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Seja T uma árvore geradora de um grafo G. Para toda aresta t de T, as duas componentes de T–t definem um corte em G. Diremos que esse é o corte determinado por T–t. A única aresta de T que atravessa o corte é t.&lt;br /&gt;
&lt;br /&gt;
Segunda Propriedade da Troca: Seja T uma árvore geradora de um grafo G. Para qualquer aresta t de T e qualquer aresta e de G que atravesse o corte determinado por T–t, o grafo T – t + e é uma árvore geradora de G.&lt;br /&gt;
Exemplo: Seja T a árvore geradora definida pelas cinco arestas "internas" da figura. Seja t a aresta 4-5. O corte determinado por T–t tem três arestas: 0-1, 4-5 e 3-2. Se e é uma qualquer dessas arestas então T–t+e é uma árvore geradora.&lt;br /&gt;
&lt;br /&gt;
&lt;img src='http://i722.photobucket.com/albums/ww221/allgoritmos/g1-1.png'/&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fonte:&lt;/b&gt; &lt;a href='http://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/spanningtrees.html' target='_blank'&gt;IME&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-4978236279602433723?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/WJg04P2GYdQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/4978236279602433723/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/arvore-geradora-em-grafos.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4978236279602433723?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/4978236279602433723?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/WJg04P2GYdQ/arvore-geradora-em-grafos.html" title="Árvore Geradora em Grafos" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/arvore-geradora-em-grafos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cERXs5cSp7ImA9WxNXF0k.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-6844534475050963584</id><published>2009-10-05T08:07:00.001-04:00</published><updated>2009-10-05T09:23:24.529-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-05T09:23:24.529-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><category scheme="http://www.blogger.com/atom/ns#" term="implementações" /><title>Caminhos mínimos</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TgIaCOYZEZHzpliEGSJ2nS6jP-w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TgIaCOYZEZHzpliEGSJ2nS6jP-w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TgIaCOYZEZHzpliEGSJ2nS6jP-w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TgIaCOYZEZHzpliEGSJ2nS6jP-w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Caminhos mínimos&lt;br /&gt;
&lt;br /&gt;
&lt;div align='justify'&gt;&lt;b&gt;Distância&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Um caminho C num digrafo é mínimo se não existe outro caminho com mesma origem e mesmo término que C mas comprimento menor que o de C. É claro que todo caminho mínimo é simples.&lt;br /&gt;
&lt;br /&gt;
A distância de um vértice s a um vértice t num digrafo é o comprimento de um caminho mínimo de s a t. Se não existe caminho algum de s a t, a distância de s a t é infinita. A distância de s a t é d se e somente se (1) existe um caminho de comprimento d de s a t e (2) nenhum caminho de s a t tem comprimento menor que d.&lt;br /&gt;
&lt;br /&gt;
Em geral, a distância de um vértice s a um vértice t é diferente da distância de t a s. Num grafo, entretanto, as duas distâncias são iguais.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Busca em largura e distâncias&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
O algoritmo de busca em largura foi concebido sob medida para calcular distâncias a partir de um vértice s. Ele visita todos os vértices que estão à distância 1 de s, depois todos os vértices que estão à distância 2 de s, e assim por diante.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class='cpp' name='code'&gt;int dist[maxV];
/* A função distDigrafo armazena no vetor dist a distância do vértice s a cada um dos demais vértices do digrafo G: dist[v] é a distância de s a v. Distância infinita é representada por -1.*/

void distDigrafo (int s) { 
    int v, w;
    int ini,fim;
    for (v = 0; v &lt; n; v++) dist[v] = -1;
    ini = fim = 0;
    dist[s] = 0;
    fila[ini++] = s;
    while (ini &gt; fim) {
       v = fila[fim++]; 
       for (w = 0; w &lt; n; w++)
          if (g[v][w] == 1)
             if (dist[w] == -1) { 
                dist[w] = dist[v] + 1;
                fila[ini++] = w; 
             }
    }
}
&lt;/pre&gt;
&lt;br/&gt;
No início de cada iteração, a fila consiste em&lt;br/&gt;
&lt;br/&gt;
1. zero ou mais vértices à distância d de s,&lt;br/&gt;
2. seguidos de zero ou mais vértices à distância d+1 de s,&lt;br/&gt;
para algum d. Essa propriedade permite concluir que, no início de cada iteração, para todo vértice x, se dist[x] é diferente de -1 então dist[x] é a distância de s a x.&lt;br/&gt;&lt;br/&gt;
Exemplo&lt;br/&gt;&lt;br/&gt;

Considere o grafo (digrafo simétrico) definido pelo conjunto de arestas abaixo.&lt;br/&gt;
Represente o grafo por sua matriz de adjacência.&lt;br/&gt;
&lt;br/&gt;
0-2 2-6 6-4 4-5 5-0 0-7 7-1 7-4 3-4 3-5&lt;br/&gt;
&lt;br/&gt;
Agora use a função distDigrafo para calcular as distâncias a partir do vértice 0. &lt;br/&gt;Eis o estado do vetor dist no início de sucessivas iterações (com "*" no lugar de "-1"):&lt;br/&gt;
&lt;br/&gt;
0 1 2 3 4 5 6 7&lt;br/&gt;
---------------&lt;br/&gt;
0 * * * * * * * &lt;br/&gt;
0 * 1 * * 1 * 1 &lt;br/&gt;
0 * 1 * * 1 2 1 &lt;br/&gt;
0 * 1 2 2 1 2 1 &lt;br/&gt;
0 2 1 2 2 1 2 1 &lt;br/&gt;
&lt;br/&gt;
&lt;b&gt;Caminhos mínimos e arborescência de distâncias&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;

Se acrescentar ao código de distDigrafo o cálculo de um vetor de pais &lt;i&gt;pai&lt;/i&gt;, teremos uma representação da arborescência de busca em largura. &lt;br/&gt;No presente contexto, essa árvore pode ser chamada arborescência das distâncias: para cada vértice x tal que dist[x] é diferente de -1, o único caminho de s a x na arborescência é um caminho mínimo no digrafo. O fragmento de código abaixo imprime o inverso desse caminho:&lt;br/&gt;

&lt;pre class='cpp' name='code'&gt;for (v = x; v != s; v = pai[v])
    printf("%d-", v)
printf("%d\n", s)
&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;

&lt;b&gt;Desempenho&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;

A função distDigrafo é linear: ela consome tempo proporcional a V2 no pior caso. A variante dessa função para listas de adjacência consome tempo proporcional a V+E.&lt;br/&gt;&lt;br/&gt;

A versão de distDigrafo que calcula a arborescência de distâncias também é linear.&lt;br/&gt;&lt;br/&gt;

&lt;b&gt;Digrafos com custos nos arcos&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;

Muitas aplicações associam um número a cada arco de um digrafo. Diremos que esse número é o custo da arco. Vamos supor, em geral, que esses números são do tipo double, podendo ser positivos, negativos, ou nulos. Essa associação de custos aos arcos pode ser entendida como uma função que leva o conjunto de arcos num conjunto de números.&lt;br/&gt;&lt;br/&gt;

Dependendo da aplicação, pode ser mais apropriado dizer "peso" ou "comprimento" no lugar de "custo". [Sedgewick diz weight no lugar do nosso "custo". Mas isso aumenta o número de variáveis cujo nome começa "w", o que torna os programas menos legíveis.]&lt;br/&gt;&lt;br/&gt;

&lt;b&gt;Grafos com custos nas arestas&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;

Grafos com custos nas arestas têm uma peculiaridade previsível: os dois arcos que constituem cada aresta têm o mesmo custo. O custo de uma aresta, nesse caso, é o custo de qualquer dos dois arcos que constituem a aresta.&lt;br/&gt;&lt;br/&gt;
&lt;b&gt;Exercícios para Fixação&lt;/b&gt;&lt;br/&gt;&lt;br/&gt;

1. O código distDigrafo utiliza matriz ou lista de adjacências para representar o grafo? Implemente o mesmo código para o outro tipo de representação.&lt;br/&gt;
2. Como ficaria esse código com o cálculo do vetor de pais?&lt;br/&gt;
3. Qual é o resultado de trocarmos a bfs por dfs neste código?&lt;br/&gt;&lt;br/&gt;

&lt;b&gt;Fonte:&lt;/b&gt; &lt;a href='http://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/shortestpaths.html' target='_blank'&gt;IME&lt;/a&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-6844534475050963584?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/BjnDchO-1Bw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/6844534475050963584/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/caminhos-minimos.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/6844534475050963584?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/6844534475050963584?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/BjnDchO-1Bw/caminhos-minimos.html" title="Caminhos mínimos" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/caminhos-minimos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04ARno6fip7ImA9WxNXF0w.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-2097300296818736378</id><published>2009-10-05T00:08:00.003-04:00</published><updated>2009-10-05T00:12:27.416-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-05T00:12:27.416-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><category scheme="http://www.blogger.com/atom/ns#" term="implementações" /><title>Busca em Largura</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dasqnVY4UpLEv0yt92-GeOgMWRw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dasqnVY4UpLEv0yt92-GeOgMWRw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dasqnVY4UpLEv0yt92-GeOgMWRw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dasqnVY4UpLEv0yt92-GeOgMWRw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align="justify"&gt;A busca em largura, também conhecida como busca BFS (= breadth-first search), está intimamente relacionada com o conceito de distância entre vértices. Quando aplicada a uma arborescência, a busca BFS faz uma varredura "por níveis".&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;BFS versus DFS&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A diferença mais marcante entre a busca em largura e a busca em profundidade está na estrutura de dados auxiliar empregada por uma das estratégias e pela outra. A busca em largura usa uma fila (de vértices), enquanto a busca em profundidade usa uma pilha. (Na versão recursiva da busca em profundidade, a pilha não aparece explicitamente pois é administrada pelo mecanismo de recursão.) Mas há várias outras diferenças, mais superficiais, entre os dois algoritmos:&lt;br /&gt;
&lt;br /&gt;
- na busca em profundidade, o próprio algoritmo escolhe o vértice inicial, enquanto a busca em largura começa tipicamente num vértice especificado pelo usuário;&lt;br /&gt;
- a busca em profundidade visita, tipicamente, todos os vértices do digrafo, enquanto a busca em largura visita apenas os vértices que podem ser atingidos a partir do vértice inicial;&lt;br /&gt;
- a busca em profundidade é descrita, usualmente, em estilo recursivo, enquanto a busca em largura é descrita em estilo iterativo.&lt;br /&gt;
&lt;br /&gt;
O fato é que, apesar da semelhança entre a siglas, a busca DFS e a busca BFS são muito diferentes e têm aplicações muito diferentes.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Busca em largura&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A busca em largura começa por um vértice, digamos s, especificado pelo usuário. O algoritmo visita s, depois visita todos os vértices que estão à distância 1 de s, depois todos os vértices que estão à distância 2 de s, e assim por diante. &lt;br /&gt;
&lt;br /&gt;
Para implementar essa idéia, o algoritmo usa uma &lt;b&gt;fila de vértices&lt;/b&gt;. Essa fila contém todos os vértices já visitados cujos vizinhos ainda não foram visitados. &lt;br /&gt;
&lt;br /&gt;
A ordem em que os vértices são visitados é registrada num vetor &lt;i&gt;ordemvisit&lt;/i&gt; indexado pelos vértices, à semelhança do que fizemos ao estudar busca em profundidade.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cpp" name="code"&gt;#define MAXV 10000
int cnt, ordemvisit[MAXV];
int fila[MAXV];
int ini,fim;
/* A função bfsDigrafo visita todos os vértices do digrafo G que podem ser alcançados a partir do vértice s. A ordem em que os vértices são visitados é registrada no vetor ordemvisit. */

void bfsDigrafo (int s) { 
   int v, w;
   cnt = 0;
   for (v = 0; v &amp;lt; n; v++) ordemvisit[v] = -1;
   ordemvisit[s] = cnt++;
   ini = fim = 0;
   fila[ini++] = s; 
   while (ini &amp;gt; fim) {
       v = fila[fim++]; 
       for (w = 0; w &amp;lt; n; w++)
           if (g[v][w] == 1)
              if (ordemvisit[w] == -1) { 
                 ordemvisit[w] = cnt++; 
                 fila[ini++] = w; 
             }
   }
}
&lt;/pre&gt;&lt;br /&gt;
No início de cada iteração valem as seguinte propriedades:  1. todo vértice que está na fila já foi visitado; 2. se um vértice v já foi visitado mas algum de seus vizinhos ainda não foi visitado, então v está na fila.  (Um vértice x já foi visitado se e somente se ordemvisit[x] é diferente de -1.) Cada vértice entra na fila no máximo uma vez. Portanto, basta que a fila tenha espaço suficiente para V vértices.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Arborescência de busca em largura&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A busca em largura a partir de um vértice s descreve, implicitamente, uma arborescência com raiz s. Essa arborescência é conhecida como arborescência de busca em largura (= BFS tree). Podemos representar essa arborescência explicitamente por um vetor de pais &lt;i&gt;pai&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
[Muita gente diz "árvore de busca" no lugar do meu "arborescência de busca". Infelizmente, a palavra "árvore" também é usada para designar um outro conceito, o que pode causar confusão.]&lt;br /&gt;
&lt;br /&gt;
No início de cada iteração, cada vértice que está na fila é uma folha da arborescência representada por pai.  &lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Desempenho&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A função bfsDigrafo é linear: ela consome tempo proporcional a V^2 no pior caso. A variante dessa função para listas de adjacência consome tempo proporcional a V+E.  &lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Exercícios para Fixação&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
1. O código bfsDigrafo utiliza matriz ou lista de adjacências para representar o grafo?&lt;br /&gt;
2. Como ficaria esse código com o cálculo do vetor de pais?&lt;br /&gt;
3. O que a bfs faz que a dfs não pode fazer?&lt;br /&gt;
4. Faça um algoritmo que determine o caminho mínimo entre dois vértices usando bfs, o peso de todas as arestas é o mesmo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fonte:&lt;/b&gt; &lt;a href="http://www.ime.usp.br/%7Epf/algoritmos_para_grafos/aulas/bfs.html" target="_blank"&gt;IME&lt;/a&gt; &lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-2097300296818736378?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/7VEZni8aWUc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/2097300296818736378/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/busca-em-largura.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/2097300296818736378?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/2097300296818736378?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/7VEZni8aWUc/busca-em-largura.html" title="Busca em Largura" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/busca-em-largura.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QFRH4-eyp7ImA9WxNXFE8.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-857679983833779919</id><published>2009-10-01T14:21:00.001-04:00</published><updated>2009-10-01T14:21:55.053-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-01T14:21:55.053-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="busca google" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>Busca Google com Novas Funcionalidades</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LP--E3PTfa6WJ0rgEO60Sb8vTlI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LP--E3PTfa6WJ0rgEO60Sb8vTlI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LP--E3PTfa6WJ0rgEO60Sb8vTlI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LP--E3PTfa6WJ0rgEO60Sb8vTlI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align="justify"&gt;Melhorias interessantes são anunciadas pela Google para o painel lateral de seu mecanismo de busca, lançado no início deste ano. No total são &lt;b&gt;9 novas funcionalidades&lt;/b&gt;:&lt;br /&gt;
publicações apenas da última hora, por um intervalo de datas específico, mais sites de compras, menos sites de compra, páginas já visitadas, páginas ainda não visitadas, livros, blogs e notícias. &lt;br /&gt;
&lt;br /&gt;
Graças a isso, agora você pode, por exemplo, restringir os resultados da pesquisa para sites que foram atualizados na última hora, ou você pode dizer ao Google para ajustar o número de sites de compras que aparecem em uma página de resultados de pesquisa.&lt;br /&gt;
&lt;br /&gt;
A Google irá começar a publicar essas novas funcionalidades durante o dia de hoje (01/10/2009) e pretende disponibilizar todas elas até o fim deste dia (pelo menos em inglês).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Resultados de pesquisa&lt;/b&gt;&lt;br /&gt;
Agora você poderá pesquisar apenas páginas não visitadas, para isso basta estar logado em sua conta Google e possuir histórico de web ativado.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Livros, blogs e notícias&lt;/b&gt;&lt;br /&gt;
Essa funcionalidade de pesquisa por livros e blogs já existe, mas agora você poderá filtrar suas buscas por blogs e notícias também.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Compras&lt;/b&gt;&lt;br /&gt;
Limitar o número de sites de compras talvez seja a funcionalidade mais agradável. Muitas vezes não queremos comprar nada e agora poderemos minimizar o número de sites de compras que serão apresentado: &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.nytimes.com/external/readwriteweb/2009/10/01/01readwriteweb-googles-search-options-panel-gets-new-featur-9769.html"&gt;Fonte 1&lt;/a&gt;&amp;nbsp; &lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-857679983833779919?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/xersGz3k-hc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/857679983833779919/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/10/busca-google-com-novas-funcionalidades.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/857679983833779919?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/857679983833779919?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/xersGz3k-hc/busca-google-com-novas-funcionalidades.html" title="Busca Google com Novas Funcionalidades" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/10/busca-google-com-novas-funcionalidades.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEBRnk7cCp7ImA9WxNQE0s.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-590900235877254090</id><published>2009-09-18T23:07:00.004-04:00</published><updated>2009-09-19T09:40:57.708-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-19T09:40:57.708-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="maratona de programação" /><category scheme="http://www.blogger.com/atom/ns#" term="notícias" /><title>Maratona de Programação, Ao Vivo</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EHTd3SPBu4gNhSs4TMKNbieRIQg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EHTd3SPBu4gNhSs4TMKNbieRIQg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EHTd3SPBu4gNhSs4TMKNbieRIQg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EHTd3SPBu4gNhSs4TMKNbieRIQg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;Está chegando a hora, hoje (19/09) todo Brasil estará participando da Maratona de Programação (ACM-ICPC) etapa sub-regional.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://maratona.ime.usp.br/vagas09.html"&gt;Confira a lista de Vagas previstas para a Final Brasileira!&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;Infelizmente esse ano em minha sede, &lt;a href="http://www.comp.uems.br/maratona/2009"&gt;UEMS&lt;/a&gt; (Dourados/MS), não temos uma vaga garantida e teremos que disputar com a UnB além da FIP Anhanguera que virá participar aqui em Dourados.&lt;br /&gt;
&lt;br /&gt;
Assim que tivermos os resultados estarei divulgado aqui no blog. Mas você poderá acompanhar &lt;b&gt;AO VIVO &lt;/b&gt;o score da sede de Dourados/MS.&lt;br /&gt;
&lt;br /&gt;
A competição irá começar as 14:00 horário de Brasília. Fique ligado!&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;Acesso: http://200.181.125.91/boca/ &lt;/span&gt;&lt;br /&gt;
Usuário e senha: score&lt;br /&gt;
&lt;br /&gt;
Então fica a torcida, boa sorte a todos maratonistas (inclusive eu). &lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-590900235877254090?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/UJZyLY1XihM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/590900235877254090/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/09/maratona-de-programacao-ao-vivo.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/590900235877254090?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/590900235877254090?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/UJZyLY1XihM/maratona-de-programacao-ao-vivo.html" title="Maratona de Programação, Ao Vivo" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/09/maratona-de-programacao-ao-vivo.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cHSXY8fip7ImA9WxNQEkQ.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-7860814351770589783</id><published>2009-09-18T14:09:00.003-04:00</published><updated>2009-09-18T14:37:18.876-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-18T14:37:18.876-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="novidades" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>Orkut divulgando nossos eventos/vendas de graça</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tm-RSvKKWu6qj6-F2ubirsA_P1c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tm-RSvKKWu6qj6-F2ubirsA_P1c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tm-RSvKKWu6qj6-F2ubirsA_P1c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tm-RSvKKWu6qj6-F2ubirsA_P1c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://i722.photobucket.com/albums/ww221/allgoritmos/orkut-promova.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="93" src="http://i722.photobucket.com/albums/ww221/allgoritmos/orkut-promova.png" width="200" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;Depois de muito tempo de espera, finalmente a funcionalidade do orkut chamada de "Promote" ou Promova em português está começando a ser disponibilizada nos perfis do Orkut.&lt;br /&gt;
&lt;br /&gt;
A função do Promova que assemelha-se com o Twitter, ou mais similar até com o &lt;b&gt;Yahoo! Meme &lt;/b&gt;onde é possível compartilhar textos longos, imagens e vídeos sendo restrito apenas as imagens hospedadas no álbum de fotos do orkut e vídeos do YouTube. Quando o conteúdo é postado, um gerenciado permite visualizar quantas pessoas visualizaram, clicaram ou promoveram, e ainda, uma escala mede o alcance que teve a sua promoção.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://i722.photobucket.com/albums/ww221/allgoritmos/promova-01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://i722.photobucket.com/albums/ww221/allgoritmos/promova-01.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Confira o vídeo que explica essa nova função:&lt;br /&gt;
&lt;object height="295" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/KWKUwc6Mqec&amp;amp;hl=pt-br&amp;amp;fs=1&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/KWKUwc6Mqec&amp;amp;hl=pt-br&amp;amp;fs=1&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
Fonte: &lt;a href="http://googlediscovery.com/"&gt;Google Discovery&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-7860814351770589783?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/OmQ3K4OlBLU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/7860814351770589783/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/09/orkut-divulgando-nossos-eventos.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/7860814351770589783?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/7860814351770589783?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/OmQ3K4OlBLU/orkut-divulgando-nossos-eventos.html" title="Orkut divulgando nossos eventos/vendas de graça" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/09/orkut-divulgando-nossos-eventos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcMSXY4cCp7ImA9WxNRFEs.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-7824384199630542898</id><published>2009-09-08T22:20:00.003-04:00</published><updated>2009-09-08T22:24:48.838-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-08T22:24:48.838-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><category scheme="http://www.blogger.com/atom/ns#" term="implementações" /><category scheme="http://www.blogger.com/atom/ns#" term="algoritmos" /><title>Articulações e Biconexão</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xRLp9D8YyxJEFFh30F7rL5tYruA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xRLp9D8YyxJEFFh30F7rL5tYruA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xRLp9D8YyxJEFFh30F7rL5tYruA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xRLp9D8YyxJEFFh30F7rL5tYruA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align="justify"&gt;Aqui trataremos de grafos que deixam de ser &lt;a href="http://www.allgoritmos.com/2009/09/conexao-digrafos-conexos.html" target="_blank"&gt;conexos&lt;/a&gt; quando perdem um de seus vértices. Ela se restringe a grafos (embora o conceito também faça sentido em digrafos não-&lt;a href="http://www.allgoritmos.com/2009/06/digrafos.html" target="_blank"&gt;simétricos&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Articulações em grafos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Uma articulação (= articulation point) ou vértice de corte (= cut vertex) de um grafo é um vértice cuja remoção aumenta o número de &lt;a href="http://www.allgoritmos.com/2009/08/componentes-de-grafos.html" target="_blank"&gt;componentes&lt;/a&gt; do grafo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Algoritmo&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://javafree.uol.com.br/artigo/874965/GRAFOS-Articulacoes-e-Biconexao.html"&gt;código&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Biconexão&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Um grafo é  biconexo (= biconnected)  ou  2-conexo  se é conexo e não tem articulações.  Portanto, é preciso remover pelo menos 2 vértices de um grafo biconexo para que ele deixe de ser conexo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fato básico importante&lt;/b&gt;:  Um grafo é biconexo se e somente se, para cada par (s,t) de seus vértices, existem (pelo menos) dois caminhos de s e t sem vértices internos em comum  (ou seja, s e t são os únicos vértices comuns aos dois caminhos).&lt;/div&gt;&lt;img src="http://i722.photobucket.com/albums/ww221/allgoritmos/biconexo.jpg" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Exercícios para Fixação&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
1. Faça esse algoritmo para lista de adjacências.&lt;br /&gt;
2. Mostre que todo grafo biconexo é aresta-biconexo.&lt;br /&gt;
3. Qual o número mínimo de arestas que um grafo biconexo com V vértices deve ter?&lt;br /&gt;
4. Porque é importante identificar pontos de articulação? Dê uma situação prática.&lt;br /&gt;
5. Explique com suas palavras o que é um grafo biconexo.&lt;br /&gt;
6. Qual a diferença entre pontes e articulações?&lt;br /&gt;
7. Modifique o algoritmo acima para que ele somente diga se existe ponto de articulação ou não.&lt;br /&gt;
&lt;br /&gt;
Referência: &lt;a href="http://www.ime.usp.br/%7Epf/algoritmos_para_grafos/aulas/articulations.html" target="_blank"&gt;IME&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-7824384199630542898?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/G1xS-0pCv4Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/7824384199630542898/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/09/articulacoes-e-biconexao.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/7824384199630542898?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/7824384199630542898?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/G1xS-0pCv4Y/articulacoes-e-biconexao.html" title="Articulações e Biconexão" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/09/articulacoes-e-biconexao.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIHQn4zcCp7ImA9WxNRFEg.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-1740649871295949263</id><published>2009-09-08T18:55:00.002-04:00</published><updated>2009-09-08T18:55:33.088-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-08T18:55:33.088-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><category scheme="http://www.blogger.com/atom/ns#" term="implementações" /><category scheme="http://www.blogger.com/atom/ns#" term="algoritmos" /><title>Pontes em grafos e aresta-biconexão</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2fnmTk4ji_2YZHjkHhYbUyCXZ-Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2fnmTk4ji_2YZHjkHhYbUyCXZ-Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2fnmTk4ji_2YZHjkHhYbUyCXZ-Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2fnmTk4ji_2YZHjkHhYbUyCXZ-Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align="justify"&gt;Aqui tratamos de grafos que &lt;b&gt;deixam de ser &lt;a href="http://www.allgoritmos.com/2009/09/conexao-digrafos-conexos.html" target="_blank"&gt;conexos&lt;/a&gt;&lt;/b&gt; quando perdem &lt;b&gt;uma de suas arestas&lt;/b&gt;. Ela se restringe a grafos, pois os conceitos discutidos não fazem sentido em digrafos não-&lt;a href="http://www.allgoritmos.com/2009/06/digrafos.html" target="_blank"&gt;simétricos&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pontes em grafos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Uma aresta de um grafo &lt;b&gt;é uma ponte&lt;/b&gt; (= bridge = separation edge) &lt;b&gt;se ela é a única aresta que &lt;a href="http://www.allgoritmos.com/2009/09/conexao-digrafos-conexos.html" target="_blank"&gt;atravessa algum corte&lt;/a&gt; do grafo&lt;/b&gt;. [Pontes são também conhecidas com arestas de corte, mas nós não vamos usar essa terminologia.]&lt;br /&gt;
&lt;br /&gt;
Em outras palavras, uma ponte é uma aresta cuja remoção aumenta o número de &lt;a href="http://www.allgoritmos.com/2009/08/componentes-de-grafos.html" target="_blank"&gt;componentes&lt;/a&gt; do grafo.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Problema&lt;/b&gt;: Encontrar as pontes de um grafo dado.&lt;br /&gt;
&lt;br /&gt;
Poderíamos aplicar cegamente a definição de ponte para resolver o problema, mas é possível fazer coisa melhor.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Pontes e busca em profundidade&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
É possível encontrar as pontes de um grafo de maneira muito eficiente. O ponto de partida é o seguinte fato básico: em qualquer grafo, uma aresta é uma ponte se e somente se não faz parte de um &lt;a href="http://www.allgoritmos.com/2009/09/ciclos-em-grafos-e-digrafos.html" target="_blank"&gt;ciclo não-trivial&lt;/a&gt;. (Em outras palavras, toda aresta é de um e apenas um de dois tipos: ou ela é uma ponte ou pertence a um ciclo não-trivial.)&lt;br /&gt;
&lt;br /&gt;
Se fizermos uma busca em profundidade no grafo, um dos dois arcos que constituem qualquer ponte será necessariamente um &lt;a href="http://www.allgoritmos.com/2009/08/arborescencia-de-busca-em-profundidade.html" target="_blank"&gt;arco de arborescência&lt;/a&gt; (por que?). Agora observe a seguinte&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Propriedade&lt;/b&gt;: Em qualquer busca em profundidade, um arco v-w da floresta DFS faz parte (juntamente com w-v) de uma ponte se e somente se não existe arco de retorno que ligue um &lt;a href="http://www.allgoritmos.com/2009/08/arborescencias.html" target="_blank"&gt;descendente de w a um ancestral de v&lt;/a&gt;.&lt;br /&gt;
(Os descendentes e ancestrais de que trata a propriedade não são necessariamente próprios.) Para tirar proveito dessa propriedade, vamos calcular, para cada vértice v, o menor &lt;a href="http://www.allgoritmos.com/2009/08/busca-em-profundidade-dfs.html" target="_blank"&gt;número de pré-ordem&lt;/a&gt; (= lowest preorder number) que pode ser alcançado a partir de v. Esse número será denotado por&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;menorpre[v].&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
Explico melhor: Digamos, só para efeito desta explicação, que um caminho é interessante se&lt;br /&gt;
&lt;br /&gt;
- começa em v,&lt;br /&gt;
- "desce" pela &lt;a href="http://www.allgoritmos.com/2009/08/arborescencia-de-busca-em-profundidade.html" target="_blank"&gt;arborescência de busca em profundidade&lt;/a&gt;,&lt;br /&gt;
- e finalmente percorre no máximo um arco de retorno.&lt;br /&gt;
&lt;br /&gt;
(Por exemplo, todo caminho de comprimento 0 que começa em v é interessante. Outro exemplo: um caminho de comprimento 1 que começa em v e percorre um só arco de retorno é interessante.) Digamos que o valor de um caminho interessante é lbl[z], sendo z o último vértice do caminho. Então low[v] é, por definição, o valor de um caminho interessante de valor mínimo.&lt;br /&gt;
&lt;br /&gt;
É claro que &lt;b&gt;menorpre[v] ≤ ordemvisit[v]&lt;/b&gt; para todo vértice v. Digo mais: para todo arco v-w do grafo,&lt;br /&gt;
&lt;br /&gt;
- se v-w é um arco de arborescência (e portanto v é pai de w) então menorpre[v] ≤ menorpre[w];&lt;br /&gt;
- se v-w é uma arco de retorno (e portanto ordemvisit[v] &amp;gt; ordemvisit[w]) então menorpre[v] ≤ ordemvisit[w].&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Algoritmo das pontes&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A propriedade acima pode ser reformulada assim: em qualquer floresta de busca em profundidade de um grafo, um arco de arborescência v-w faz parte de uma ponte se e somente se menorpre[w] == ordemvisit[w].&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cpp" name="code"&gt;#define MAXV 100 //número máximo de vértices
int G[MAXV][MAXV]; //grafo representado por matriz de adjacência
int ordemvisit[MAXV]; //marca a ordem de visitação dos vértices
int menorpre[MAXV]; //menor o menor número de pré-ordem que pode ser alcançado a partir de v
int pai[MAXV]; //vetor de pai, pai de X é pai[X]
int n; //número de vértices neste grafo
int count; //contador
int countpontes; //contador de pontes

//A função abaixo calcula o número de pontos, &lt;i&gt;countpontes&lt;/i&gt;, do grafo G e imprime todas as pontes
void todasPontes(){
 int v;
 for( v = 0 ; v &amp;lt; n ; ++v ){
  ordemvisit[v] = -1;
 }
 for( v = 0 ; v &amp;lt; n ; ++v ){
  if(ordemvisit[v] == -1){
   pai[v] = v;
   ponte(v);
  }
 }
}

void ponte(int v){
 int p, v;
 ordemvisit[v] = count++;
 menorpre[v] = ordemvisit[v];
 for( p = 0 ; p &amp;lt; n ; ++p ){
  if(ordemvisit[p] == -1){
   pai[p] = v;
   ponte(p);
   if ( menorpre[v] &amp;gt; menorpre[p])
    menorpre[v] = menorpre[p];
   if ( menorpre[p] == ordemvisit[p]){
    countpontes++;
    printf("%d-%d\n", v, p);
   }
  }
  else if( p != pai[v] &amp;amp;&amp;amp; menorpre[v] &amp;gt; ordemvisit[p] )
   menorpre[v] = ordemvisit[p];
 }
}&lt;/pre&gt;&lt;br /&gt;
O teste  "if (p != pai[v])"  garante que v-w é um arco de retorno (e não um arco-pai).&lt;br /&gt;
&lt;br /&gt;
A função todasPontes é linear: ela consome tempo proporcional a V+E.  A variante dessa função para matrizes de adjacência consome tempo proporcional a V².&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Aresta-biconexão&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Um grafo é aresta-biconexo (= edge-connected) ou 2-aresta-conexo se for conexo e não tiver pontes. Portanto, é preciso remover pelo menos duas arestas de um grafo aresta-biconexo para que ele deixe de ser conexo.&lt;br /&gt;
&lt;br /&gt;
Fato básico importante: Um grafo é aresta-biconexo se e somente se, para cada par (s,t) de seus vértices, existem (pelo menos) dois caminhos de s a t sem arestas em comum.&lt;br /&gt;
&lt;br /&gt;
Uma componente aresta-biconexa (= edge-connected component) de um grafo é qualquer &lt;a href="http://www.allgoritmos.com/2009/08/componentes-de-grafos.html" target="_blank"&gt;componente&lt;/a&gt; do grafo que se obtém depois que todas as pontes são removidas.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Exercícios para Fixação&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
1. Mostre que todas as arestas de qualquer floresta são pontes. A recíproca é verdadeira?&lt;br /&gt;
2. Escreva uma função que calcule menorpre[v] para cada vértice v de um grafo dado.&lt;br /&gt;
3. Diga o que a função &lt;b&gt;ponte&lt;/b&gt; faz.&lt;br /&gt;
4. Execute a função todasPontes para encontrar as pontos dos grafos da figura abaixo:&lt;br /&gt;
&lt;img src="http://i722.photobucket.com/albums/ww221/allgoritmos/grafos.gif" /&gt;&lt;br /&gt;
5. Escreva uma função que receba um grafo G e devolva 1 se o grafo é aresta-biconexo e devolva 0 em caso contrário. (Sugestão: modifique os códigos já apresentados nesta aula)&lt;br /&gt;
6. Qual o número mínimo de arestas de um grafo aresta-biconexo que tem V vértices?&lt;br /&gt;
&lt;br /&gt;
Referência: &lt;a href="http://www.ime.usp.br/%7Epf/algoritmos_para_grafos/aulas/bridges.html" target="_blank"&gt;IME&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-1740649871295949263?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/zanMnSSYXFs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/1740649871295949263/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/09/pontes-em-grafos-e-aresta-biconexao.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/1740649871295949263?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/1740649871295949263?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/zanMnSSYXFs/pontes-em-grafos-e-aresta-biconexao.html" title="Pontes em grafos e aresta-biconexão" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/09/pontes-em-grafos-e-aresta-biconexao.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MHQncyeSp7ImA9WxNRFEk.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-5736553724156519894</id><published>2009-09-08T18:37:00.000-04:00</published><updated>2009-09-08T18:37:13.991-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-08T18:37:13.991-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><title>Conexão: digrafos conexos</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/A078G6P1AP64Qp2LhUcA0dbdN98/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/A078G6P1AP64Qp2LhUcA0dbdN98/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/A078G6P1AP64Qp2LhUcA0dbdN98/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/A078G6P1AP64Qp2LhUcA0dbdN98/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;A grosso modo, um digrafo é conexo se for "união disjunta" de dois digrafos menores. A definição precisa do conceito depende da idéia de corte. No caso de grafos (ou seja, digrafos simétricos), a caracterização da conexão envolve a idéia de &lt;a href='http://www.allgoritmos.com/2009/08/caminhos-em-digrafos.html' target='_blank'&gt;caminho&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Cortes&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Um &lt;b&gt;corte&lt;/b&gt; (= cut) de um digrafo é uma bipartição do conjunto de vértices do digrafo. Em outras palavras, um corte é um par de conjuntos de vértices, ambos não-vazios, tal que todo vértice do digrafo pertence a um e apenas um dos conjuntos do par.&lt;br /&gt;
&lt;br /&gt;
Dado um corte (X,Y) de um digrafo, dizemos que um arco pertence ao corte, ou atravessa o corte, se tiver uma ponta em X e outra em Y. Um corte é vazio se não for atravessado por nenhum arco.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Digrafos conexos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Um &lt;b&gt;digrafo é fracamente conexo&lt;/b&gt; (= weakly connected) se não tem cortes vazios. [A propósito, o conceito de digrafo fortemente conexo é mais complexo e será discutido em outra ocasião.] Portanto, um digrafo é fracamente conexo se, para toda bipartição (X,Y) de seu conjunto de vértices, algum arco tem uma ponta em X e outra em Y.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Grafos conexos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
O conceito de conexão é particularmente importante em digrafos simétricos. Nesse caso, o "fracamente" é omitido: &lt;b&gt;se um grafo não tem cortes vazios&lt;/b&gt;, dizemos simplesmente que ele é conexo (= connected). Assim, se X é um conjunto de vértices de um grafo conexo G então alguma aresta de G tem uma ponta em X e outra fora de X, a menos que X seja vazio ou contenha todos os vértices de G.&lt;br /&gt;
&lt;br /&gt;
Referência: &lt;a href='http://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/connected.html' target='_blank'&gt;IME&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-5736553724156519894?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/6sFAD8OBngU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/5736553724156519894/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/09/conexao-digrafos-conexos.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/5736553724156519894?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/5736553724156519894?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/6sFAD8OBngU/conexao-digrafos-conexos.html" title="Conexão: digrafos conexos" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/09/conexao-digrafos-conexos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMFQH88fCp7ImA9WxNREko.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-9161094965242767608</id><published>2009-09-06T16:24:00.001-04:00</published><updated>2009-09-06T19:06:51.174-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-06T19:06:51.174-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><category scheme="http://www.blogger.com/atom/ns#" term="implementações" /><category scheme="http://www.blogger.com/atom/ns#" term="algoritmos" /><title>Grafos bipartidos e ciclos ímpares</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WiGfrCaGrLsO1J3IKEHThvzRpAA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WiGfrCaGrLsO1J3IKEHThvzRpAA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WiGfrCaGrLsO1J3IKEHThvzRpAA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WiGfrCaGrLsO1J3IKEHThvzRpAA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align="justify"&gt;Aqui tratamos de grafos bipartidos, uma espécie simples, mas muito útil de grafos.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Bipartição&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Um grafo é bipartido (= bipartite) se existe uma &lt;b&gt;bipartição do seu conjunto de vértices&lt;/b&gt; tal que &lt;b&gt;cada aresta&lt;/b&gt; tem uma ponta em &lt;b&gt;uma das partes&lt;/b&gt; da bipartição e a outra ponta na &lt;b&gt;outra parte&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Outra maneira de formular a definição: um grafo é bipartido &lt;b&gt;se for possível atribuir uma de duas cores&lt;/b&gt; a cada vértice de tal forma que as pontas de &lt;b&gt;cada aresta tenham cores diferentes&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Um grafo bipartido:&lt;br /&gt;
&lt;img src="http://i722.photobucket.com/albums/ww221/allgoritmos/bipartido2.gif" /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ciclos ímpares&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
É fácil verificar que grafos que têm &lt;a href="http://www.allgoritmos.com/2009/09/ciclos-em-grafos-e-digrafos.html" target="_blank"&gt;ciclos&lt;/a&gt; de &lt;a href="http://www.allgoritmos.com/2009/08/caminhos-em-digrafos.html#comprimento" target="_blank"&gt;comprimento&lt;/a&gt; ímpar não são bipartidos. É um pouco mais difícil provar que:&lt;br /&gt;
&lt;b&gt;todo grafo sem ciclos ímpares admite bipartição&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
A função abaixo (junto com a prova de sua correção) constitui uma prova dessa fato fundamental. &lt;br /&gt;
&lt;br /&gt;
A estrutura da função é de uma busca em profundidade.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cpp" name="code"&gt;int G[MAXV][MAXV];//G está representando um grafo por matriz de adjancências
int n; //n é o número total de vértices (que são números de 0 a N-1)
int cor[MAXV];

//A função devolve 1 se o grafo  G é bipartido e devolve 0 em caso contrário. Além disso, se G é bipartido, a função atribui uma "cor" a cada vértice de G de tal forma que toda aresta tenha pontas de cores diferentes. As cores dos vértices, 0 e 1, são registradas no vetor cor indexado pelos vértices. 
int coloreGrafo(){
 int v;
 int c = 0; //representa a "cor"
 for( v = 0 ; v &amp;lt; n ; ++v ) cor[v] = -1;
 for( v = 0 ; v &amp;lt; n ; ++v )
  if(cor[v] == -1)
   if(dfsCor(v, 0) == 0) return 0;
 return 1;
}

int dfsCor(int v, int c){
 int p;
 cor[v] = 1-c; //???
 for( p = 0 ; p &amp;lt; n ; ++p ){
  if(G[v][p] == 1 &amp;amp;&amp;amp; cor[p] == -1){ //existe aresta e ainda não tem cor
   if(dfsCor(p,1-c) == 0) return 0;
  }
  else if (cor[p] == 1-c) return 0;
 }
 return 1;
}&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Exercícios para Fixação&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
1. O que faz esta linha: "&lt;i&gt;cor[v] = 1-c&lt;/i&gt;"? &lt;br /&gt;
2. Quais dos dois grafos abaixo são bipartidos? Para o grafo bipartido mostre as duas partições! &lt;br /&gt;
a) 0-1 1-2 2-3 3-0 0-4 4-5 5-2 &lt;br /&gt;
b) 0-1 1-2 2-3 3-0 4-6 0-5 5-2 &lt;br /&gt;
3. Diga o que a função dfsCor faz. &lt;br /&gt;
4. Mostre que se a função coloreGrafo devolve 0 então G tem um ciclo de comprimento ímpar. &lt;br /&gt;
5. Escreva essas duas funções para um grafo representando por lista de adjacências. &lt;br /&gt;
6. Execute o algoritmo coloreGrafo e mostre os principais passos para o grafo a seguir: &lt;br /&gt;
&lt;img src="http://i722.photobucket.com/albums/ww221/allgoritmos/bipartido1.gif" /&gt;  &lt;br /&gt;
&lt;br /&gt;
Referência: &lt;a href="http://www.ime.usp.br/%7Epf/algoritmos_para_grafos/aulas/bipartite.html" target="_blank"&gt;IME&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-9161094965242767608?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/1eYevgf0F1s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/9161094965242767608/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/09/grafos-bipartidos-e-ciclos-impares.html#comment-form" title="0 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/9161094965242767608?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/9161094965242767608?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/1eYevgf0F1s/grafos-bipartidos-e-ciclos-impares.html" title="Grafos bipartidos e ciclos ímpares" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/09/grafos-bipartidos-e-ciclos-impares.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIFQ347eyp7ImA9WxNREks.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-1255401848058237312</id><published>2009-09-06T14:58:00.002-04:00</published><updated>2009-09-06T14:58:32.003-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-06T14:58:32.003-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><category scheme="http://www.blogger.com/atom/ns#" term="implementações" /><category scheme="http://www.blogger.com/atom/ns#" term="algoritmos" /><title>Florestas e árvores</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/THWm6c_ulgfRZLeW73kaPp9UBgs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/THWm6c_ulgfRZLeW73kaPp9UBgs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/THWm6c_ulgfRZLeW73kaPp9UBgs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/THWm6c_ulgfRZLeW73kaPp9UBgs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;Uma árvore é o grafo que se obtém quando acrescentamos um arco anti-paralelo a cada arco de uma &lt;a href='http://www.allgoritmos.com/2009/08/arborescencias.html' target='_blank'&gt;arborescência&lt;/a&gt;. Embora correta, essa caracterização de árvores não é conveniente como definição. É melhor adotar uma definição mais tradicional. &lt;br /&gt;
&lt;br /&gt;
O primeiro passo da definição introduz um outro tipo de grafo: a floresta.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Florestas&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Uma floresta (= forest) é um &lt;a href='http://www.allgoritmos.com/2009/06/grafos.html' target='_blank'&gt;grafo&lt;/a&gt; sem &lt;a href='http://www.allgoritmos.com/2009/09/ciclos-em-grafos-e-digrafos.html' target='_blank'&gt;ciclos não-triviais&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Para cada arco v-w da floresta, o caminho v-w-v é um ciclo, mas esse ciclo é &lt;b&gt;trivial&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
Por exemplo, o grafo definido pelo conjunto de arestas abaixo é uma floresta.&lt;br /&gt;
0-1 0-5 1-2 1-3 1-4 6-7 6-8&lt;br /&gt;
&lt;br /&gt;
Florestas também são conhecidas como &lt;b&gt;grafos acíclicos&lt;/b&gt;. Uma folha (= leaf) de uma floresta é qualquer vértice de grau 1.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Árvores&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Uma árvore (= tree) é uma floresta conexa. Portanto, cada componente de uma floresta é um árvore.&lt;br /&gt;
&lt;br /&gt;
Por exemplo, o grafo definido pelo conjunto de arestas 0-1 0-5 1-2 1-3 1-4 é uma árvore.&lt;br /&gt;
&lt;br /&gt;
Não confunda árvores com &lt;a href='http://www.allgoritmos.com/2009/08/arborescencias.html' target='_blank'&gt;arborescências&lt;/a&gt;. Uma árvore é um digrafo simétrico, enquanto uma arborescência é um digrafo não-simétrico. As palavras "raiz", "pai" e "filho" não fazem sentido numa árvore.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Propriedade 1&lt;/b&gt;: Para cada par s,t de vértices de uma árvore existe um e um só caminho simples de s a t.&lt;br /&gt;
&lt;b&gt;Propriedade 2&lt;/b&gt;: Toda árvore com V vértices tem exatamente V-1 arestas.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Exercícios para Fixação&lt;/b&gt;&lt;br /&gt;
1. Essa afirmação está correta: "Toda árvore com V vértices tem exatamente V-1 arestas."? Porque?&lt;br /&gt;
2. Mostre que toda floresta com &lt;b&gt;V&lt;/b&gt; vértices e &lt;b&gt;C&lt;/b&gt; componentes tem exatamente &lt;b&gt;V-C&lt;/b&gt; arestas.&lt;br /&gt;
3. Prove que toda floresta com pelo menos uma aresta tem pelo menos duas folhas.&lt;br /&gt;
4. Escreva uma função que reconheça florestas. Ao receber um grafo G, a função deve devolver 1 se G é uma floresta e devolver 0 em caso contrário.&lt;br /&gt;
5. Escreva uma segunda versão para a função do exercício anterior, que imprima um ciclo não-trivial imediatamente antes de devolver 0.&lt;br /&gt;
6. Escreva uma função que reconheça árvores. Ao receber um grafo G, a função devolve 1 se G é uma árvore e devolve 0 em caso contrário.&lt;br /&gt;
&lt;br /&gt;
Referência: &lt;a href='http://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/trees.html' target='_blank'&gt;IME&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-1255401848058237312?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/ZAlBHyTX0ZU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/1255401848058237312/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/09/florestas-e-arvores.html#comment-form" title="2 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/1255401848058237312?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/1255401848058237312?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/ZAlBHyTX0ZU/florestas-e-arvores.html" title="Florestas e árvores" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/09/florestas-e-arvores.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8ESHc8fSp7ImA9WxNREks.&quot;"><id>tag:blogger.com,1999:blog-8121386274599465472.post-1619271391731266628</id><published>2009-09-06T14:35:00.002-04:00</published><updated>2009-09-06T14:46:49.975-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-06T14:46:49.975-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="grafos" /><category scheme="http://www.blogger.com/atom/ns#" term="implementações" /><category scheme="http://www.blogger.com/atom/ns#" term="algoritmos" /><title>Ciclos em grafos e digrafos</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/w5RoX7YIScGqDlVT9jcfO-dqt08/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/w5RoX7YIScGqDlVT9jcfO-dqt08/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/w5RoX7YIScGqDlVT9jcfO-dqt08/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/w5RoX7YIScGqDlVT9jcfO-dqt08/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div align="justify"&gt;Ciclos são caminhos fechados quase simples de comprimento pelo menos 2. Em grafos, os ciclos de comprimento 2 não são considerados "válidos".&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ciclos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Um ciclo (= cycle) num digrafo é um caminho fechado de comprimento pelo menos 2, sem vértices repetidos, exceto o último (que coincide com o primeiro).&lt;br /&gt;
&lt;br /&gt;
Dizemos que um arco v-w pertence a um dado ciclo se o vértice w é o sucessor de v no ciclo. Todos os arcos de um ciclo apontam no mesmo sentido, de um vértice do ciclo para o seu sucessor. Há quem goste de enfatizar esse fato dizendo "ciclo dirigido" em lugar do nosso "ciclo".&lt;br /&gt;
&lt;br /&gt;
No digrafo 0-1 0-5 1-0 1-5 2-4 3-1 5-3, os caminhos&lt;br /&gt;
&lt;br /&gt;
a) 1-5-3-1&lt;br /&gt;
b) 0-1-0&lt;br /&gt;
são ciclos. Já os caminhos abaixo, embora fechados, não são ciclos:&lt;br /&gt;
&lt;br /&gt;
a) 1-5-3-1-0-1&lt;br /&gt;
b) 1&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Ciclos em grafos&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Um ciclo é trivial se tem comprimento 2. Num grafo, ciclos triviais são ignorados, pois usam os dois arcos de uma mesma aresta.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Procurando ciclos: primeiro algoritmo&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A seguinte função implementa uma maneira óbvia mas pouco eficiente de encontrar um ciclo num &lt;b&gt;digrafo&lt;/b&gt;. A idéia é procurar, para cada arco v-w, um ciclo que passe por v-w.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cpp" name="code"&gt;//Devolve 1 se tem ciclo no digrafo G, devolve 0 caso contrário.
int G[MAXV][MAXV];//G está representando um grafo por matriz de adjancências
int n; //n é o número total de vértices (que são números de 0 a N-1)
int cicloDigrafo(){
 int v, dest, saida;
 for( v = 0 ; v &amp;lt; n ; ++v ){
  for( dest = 0 ; dest &amp;lt; n ; ++dest ){
   if( G[v][dest] == 1 &amp;amp;&amp;amp; Path(dest,v)){
    return 1;
   }
  }
 }
 return 0;
}&lt;/pre&gt;A função Path no código acima está implementada no artigo de &lt;a href="http://www.allgoritmos.com/2009/08/caminhos-em-digrafos.html" target="_blank"&gt;caminhos em digrafos&lt;/a&gt;.  A função análoga para &lt;b&gt;grafos&lt;/b&gt; é bem mais complexa porque é preciso evitar os ciclos triviais. &lt;br /&gt;
&lt;pre class="cpp" name="code"&gt;int G[MAXV][MAXV];//G está representando um grafo por matriz de adjancências
int n; //n é o número total de vértices (que são números de 0 a N-1)
//A função a seguir remove uma Aresta
void removeAresta(int o,int d){
 G[o][d] = 0;
}

//A função a seguir insere uma Aresta
void insereAresta(int o,int d){
 G[o][d] = 1;
}

//A função a seguir devolve 1 se existe um ciclo não-trivial no grafo G, caso contrário devolve 0.
int cicloGrafo(){
 int v, w;
 int dest;
 int saida;

 for( v = 0 ; v &amp;lt; n ; ++v ){
  for( dest = 0 ; dest &amp;lt; n ; ++dest ){
   if( G[v][dest] == 1 ){
    if ( v &amp;lt; dest ){
     removeAresta(dest,v);
     saida = Path(dest,v);
     insereAresta(dest,v);
     if(saida == 1)
      return 1;
    }
   }
  }
 }
 return 0;
}&lt;/pre&gt;&lt;b&gt;Procurando ciclos: algoritmo eficiente&lt;/b&gt;  A estratégia da &lt;a href="http://www.allgoritmos.com/2009/08/busca-em-profundidade-dfs.html" target="_blank"&gt;busca em profundidade&lt;/a&gt; permite encontrar ciclos de maneira muito eficiente. &lt;br /&gt;
&lt;br /&gt;
O algoritmo abaixo tem por base a seguinte observação:  em relação a qualquer &lt;a href="http://www.allgoritmos.com/2009/08/arborescencia-de-busca-em-profundidade.html" target="_blank"&gt;floresta de busca em profundidade&lt;/a&gt;:  &lt;br /&gt;
&lt;br /&gt;
todo &lt;a href="http://www.allgoritmos.com/2009/08/arborescencia-de-busca-em-profundidade.html" target="_blank"&gt;arco de retorno&lt;/a&gt; pertence a um ciclo &lt;b&gt;e&lt;/b&gt; todo ciclo tem um arco de retorno.  Função para Digrafos: &lt;br /&gt;
&lt;pre class="cpp" name="code"&gt;#define MAXV 100 //número máximo de vértices
int G[MAXV][MAXV]; //grafo representado por matriz de adjacência
int ordemvisit[MAXV]; //marca a ordem de visitação dos vértices
int n; //número de vértices neste grafo
int count; //contador

//A função abaixo devolve 1 se o digrafo G tem um ciclo, 0 caso contrário
int cicloDigrafo(){
 int v;
 for( v = 0 ; v &amp;lt; n ; ++ v )
  ordemvisit[v] = -1;
 count = 0;
 for( v = 0 ; v &amp;lt; n ; ++ v )
  if( ordemvisit[v] == -1 )
   if(cicloR(v) == 1)
    return 1;
 return 0;
}

//A função abaixo devolve 1 quando encontra um ciclo ao percorrer G a partir de v
int cicloR(int v){
 int p;
 ordemvisit[v] = count++;
 for( p = 0 ; p &amp;lt; n ; ++p ){
  if(G[v][p] == 1 &amp;amp;&amp;amp; ordemvisit[p] == -1){
   if(cicloR(p) == 1) return 1;
  }
  else if(ordemvisit[p] &amp;lt; ordemvisit[v]) return 1;
 }
 return 0;
}&lt;/pre&gt;A função &lt;i&gt;cicloGrafo&lt;/i&gt; abaixo procura ciclos não-triviais em grafos. Para evitar ciclos triviais, a função precisa ter acesso à floresta DFS. &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="cpp" name="code"&gt;#define MAXV 100 //número máximo de vértices
int G[MAXV][MAXV]; //grafo representado por matriz de adjacência
int ordemvisit[MAXV]; //marca a ordem de visitação dos vértices
int pai[MAXV]; //vetor de pai, pai de X é pai[X]
int n; //número de vértices neste grafo
int count; //contador

//A função abaixo devolve 1 se o grafo G tem um ciclo não-trivial, 0 caso contrário
int cicloGrafo(){
 int v;
 for( v = 0 ; v &amp;lt; n ; ++ v )
  ordemvisit[v] = -1;
 count = 0;
 for( v = 0 ; v &amp;lt; n ; ++ v ){
  if( ordemvisit[v] == -1 ){
   pai[v] = v;
   if(ciclo3R(v) == 1)
    return 1;
  }
 }
 return 0;
}

//A função abaixo devolve 1 quando encontra um ciclo não-trivial ao percorrer G a partir de v
int cicloR(int v){
 int p;
 ordemvisit[v] = count++;
 for( p = 0 ; p &amp;lt; n ; ++p ){
  if(G[v][p] == 1 &amp;amp;&amp;amp; ordemvisit[p] == -1){
   pai[p] = p;
   if(cicloR(p) == 1) return 1;
  }
  else if(ordemvisit[p] &amp;lt; ordemvisit[v] &amp;amp;&amp;amp; p != pai[v]) 
   return 1;
 }
 return 0;
}&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Exercícios para Fixação&lt;/b&gt;  &lt;br /&gt;
1. Escreva uma função que conte o número de ciclos em um grafo. &lt;br /&gt;
2. Escreva o algoritmo eficiente para digrafos usando lista de adjacências. &lt;br /&gt;
3. Escreva o algoritmo eficiente para grafos usando lista de adjacências. &lt;br /&gt;
4. Execute o algoritmo cicloDigrafo &lt;b&gt;eficiente&lt;/b&gt; e marque os principais passos para o digrafo da figura: &lt;br /&gt;
&lt;img src="http://i722.photobucket.com/albums/ww221/allgoritmos/g1.jpg" /&gt; &lt;br /&gt;
5. Execute o algoritmo cicloGrafo &lt;b&gt;eficiente&lt;/b&gt; e marque os principais passos para o grafo da figura: &lt;br /&gt;
&lt;img src="http://i722.photobucket.com/albums/ww221/allgoritmos/g2.jpg" /&gt; &lt;br /&gt;
6. Escreva a função removeAresta para lista de adjacências &lt;br /&gt;
7. Escreva a função insereAresta para lista de adjacências&lt;br /&gt;
&lt;br /&gt;
Referência: &lt;a href="http://www.ime.usp.br/~pf/algoritmos_para_grafos/aulas/cycles.html" target="_blank"&gt;IME&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;hr 'style: color blue' /&gt;
Este artigo pertence ao &lt;a href="http://www.allgoritmos.com"&gt;ALLgoritmos&lt;/a&gt;.&lt;br/&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8121386274599465472-1619271391731266628?l=www.allgoritmos.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/allgoritmos/~4/LnaYpV-JePE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.allgoritmos.com/feeds/1619271391731266628/comments/default" title="Postar comentários" /><link rel="replies" type="text/html" href="http://www.allgoritmos.com/2009/09/ciclos-em-grafos-e-digrafos.html#comment-form" title="2 Comentários" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/1619271391731266628?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/8121386274599465472/posts/default/1619271391731266628?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/allgoritmos/~3/LnaYpV-JePE/ciclos-em-grafos-e-digrafos.html" title="Ciclos em grafos e digrafos" /><author><name>Filipe Névola</name><uri>http://www.blogger.com/profile/14237803014844782429</uri><email>filipemkv@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="16111614955149650875" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://www.allgoritmos.com/2009/09/ciclos-em-grafos-e-digrafos.html</feedburner:origLink></entry></feed>
