1. 程式人生 > >hdu1599 【無向圖的最小環】

hdu1599 【無向圖的最小環】

杭州有N個景區,景區之間有一些雙向的路來連線,現在8600想找一條旅遊路線,這個路線從A點出發並且最後回到A點,假設經過的路線為V1,V2,....VK,V1,那麼必須滿足K>2,就是說至除了出發點以外至少要經過2個其他不同的景區,而且不能重複經過同一個景區。現在8600需要你幫他找一條這樣的路線,並且花費越少越好。

Input

第一行是2個整數N和M(N <= 100, M <= 1000),代表景區的個數和道路的條數。
接下來的M行裡,每行包括3個整數a,b,c.代表a和b之間有一條通路,並且需要花費c元(c <= 100)。

Output

對於每個測試例項,如果能找到這樣一條路線的話,輸出花費的最小值。如果找不到的話,輸出"It's impossible.".

-----------------------------------------------------------------------------------------------------------------------------------------------------------

根據Floyd的原理,在最外層迴圈做了k-1次之後,dis[i][j]則代表了i到j的路徑中,所有結點編號都小於k的最短路徑。

(就是說123456這幾個節點做了K=4次後,所有1234之間的最短路徑都確定了。當做完k=4次時,至於後面56號,像15、25、36、46等等涉及到5、6號節點的配對,它們之間的路徑可能已經求出來了,但還不能確定是不是最短的,只有當k=6都做完了以後,才能知道最終結果。)

由於題目叫我們求至少要經過兩個景區 也就是說當前的這個環至少有三個點 

現在 對於每一箇中間點(k) 我們仍然把它當做一個環的中間點 並且它是編號最大的 因為只有中間點最大 最短路i,j才是最小的(第二行說的)

路程相當於dis[i][k]+dis[k][j]+zdl[i][j](min()保證i與k,k與j肯定都是直接相連的) 

看程式碼了吧(可能有點醜陋 因為改了很久)

#include<bits/stdc++.h>
using namespace std;
//dis -> 原圖的距離 zdl ->最短路 
const int INF=1000000000;
long long n,m,ans=INF;
long long dis[105][105],zdl[105][105];

void floyd()
{

	
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=k-1;i++)
		{
			for(int j=1;j<=i-1;j++)
			{
				ans=min(ans,zdl[i][j]+dis[j][k]+dis[k][i]);
			}
		}
		
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				zdl[i][j]=min(zdl[i][j],zdl[i][k]+zdl[k][j]);
			}
		}
	}
}
int main()
{
	cin>>n>>m;
	
	for(int i=1;i<=n;i++)
	{	
		for(int j=1;j<=n;j++)
		{
			dis[i][j]=INF;
			zdl[i][j]=INF;
		}
		dis[i][i]=zdl[i][i]=0;
	}
	
	for(int i=1;i<=m;i++)
	{
		long long x,y,v;
		cin>>x>>y>>v;
		int jj=min(v,dis[x][y]);
		dis[x][y]=dis[y][x]=zdl[x][y]=zdl[y][x]=jj;

	}
	
	floyd();
	if(ans==INF)	cout<<"No solution."<<endl;
	else cout<<ans<<endl;
	return 0;
}

相關推薦

HDU-1599-find the mincost route短路

find the mincost route Time Limit: 1000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4341 

USACO4.1.3籬笆迴路

題目意思就是讓你求無向圖最小環,但是給資料的方式非常噁心。 我的用並查集+暴力的方式…… 先給每個邊的頂點標號,然後……  把A能到B,B也能到A的邊的點,給併為一個點…… 然後floyd求最小環。 floyd最小環我自己還不是非常理解…… 但是先用著,上課再想

杭電oj1599find the mincost route

           find the mincost route Time Limit: 1000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s

藍書(演算法競賽進階指南)刷題記錄——POJ1734 Sightseeing trip(

題目:poj1734. 題目大意:給定一張無向圖,求這張無向圖邊權和最小的節點大於3個的環,若有解輸出任意一個方案,否則輸出“No solution.”. 這就是一個較為簡單的floyd應用. 我們可以先把floyd模板寫下來看看floyd有什麼特殊的性質: void floyd

poj1734

要求對floyd演算法有一定的理解。 有一個神奇的地方:路徑是邊做邊更新的,防止了出現重複的點。(在不同的k時更新的路徑,中間點g[i][j]是會變化的) #include<bits/stdc++.h> using namespace std; #define

12.3日+佛洛依德處理+dijkstra處理有

  昨天的資料庫考試,題目本身都簡單的,但是感覺時間有點緊張,可能和自己有點墨跡有關。題目不怕不會做,就怕讀錯題,上了大學養成了考試“做完一遍要檢查的壞習慣”,這次沒時間檢查,所以有種做的不好的感覺。       弗洛伊德演算法是運用的動態規劃的思

floyd求——poj1734

給定一個無向圖,求出圖中由 3個及以上個點構成的環的邊權和 中的最小值。(一個點不能遍歷多次)在floyd時,先迴圈k,然後是i和j,你會發現在每次進入一個新的k迴圈時,每一個d(i,j)都儲存著從i到j,只經歷了編號不超過k-1的節點的最短路、於是,min{d(i,j)+

hdu1599

杭州有N個景區,景區之間有一些雙向的路來連線,現在8600想找一條旅遊路線,這個路線從A點出發並且最後回到A點,假設經過的路線為V1,V2,....VK,V1,那麼必須滿足K>2,就是說至除了出發點以外至少要經過2個其他不同的景區,而且不能重複經過同一個景區。現在860

CodeChefAnnual Parade -費用大流&鏈覆蓋

傳送門:Annual Parade 題解 求鏈覆蓋所有點的最小花費,考慮拆點跑最小費用最大流。 1 0

floyd求。 for(int k=1;k<=n;k++) {  for(int i=1;i<k;i++)   for(int j=1;j<k;j++)    ans=min(ans,dis[i][k]+dis[k][j]+map1[j][i])  for

[HDOJ6081] 度度熊的王國戰略(割,數據水)

eof printf ret pri sin %d logs ems ++ 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6081 無向圖求割點,應該是個論文題,16年有一篇SW算法+斐波那契堆優化的論文。 但是這數據怎麽這!

poj1966Cable TV Network——割(大流)

一個 can struct div ret memcpy AI ostream () 題目:http://poj.org/problem?id=1966 把一個點拆成入點和出點,之間連一條邊權為1的邊,跑最大流即最小割; 原始的邊權賦成inf防割; 枚舉源點和匯點,直接相鄰

vijos1423最佳路線——有模板

題目:vijos1423. 題目大意:給定一些單向直道與彎道,並且給出每條單向直道連線哪兩條彎道,讓你求出經過彎道1的邊權最小的環. 這道題我們可以將彎道看成點,將直道看成有向邊,那麼原問題其實就是求經過點1的最小環. 解決最小環問題一般用的是floyd演算法或dijkstra演算法

Vijos - 最佳路線(Floyd+有)

https://vijos.org/p/1423 題目描述 年久失修的賽道令國際汽聯十分不滿。汽聯命令主辦方立即對賽道進行調整,否則將取消其主辦權。主辦方當然必須馬上開始行動。 賽道測評人員經過了三天三夜的資料採集,選出了若干可以使用的道路和各道路行駛所需的時間。這些道路包括若干直道

洛谷P2661 資訊傳遞(帶權並查集求有)

題目描述有n個同學(編號為1到n)正在玩一個資訊傳遞的遊戲。在遊戲裡每人都有一個固定的資訊傳遞物件,其中,編號為i的同學的資訊傳遞物件是編號為Ti同學。遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日資訊告訴各自的資訊傳遞物件(注意:可能有人

點割集解法

from: http://www.cppblog.com/imky/archive/2010/08/14/123414.html 無向圖最小點割集,確定起點S,終點T。每個點都有自己的點權值vi,求最小點權和的割點集,使得S無法到達T。 解法:將每個點拆分為兩個點v和v',

hdu6311(路徑覆蓋->尤拉路徑->fleury 尤拉路徑模板)

這題主要是個套路。。就是求無向圖最小路徑覆蓋。。 與有向圖的二分圖做法不同,這個是轉化為求最少的尤拉路徑。。 尤拉圖有個結論是尤拉路徑的個數為度為奇數的點的個數/2(可以類比歐拉回路的結論) 然後求尤拉路徑的方法是fleury演算法。。其思想就是暴力dfs,然後巧妙的地

poj 2914

最小割集◎Stoer-Wagner演算法 一個無向連通網路,去掉一個邊集可以使其變成兩個連通分量則這個邊集就是割集;最小割集當然就權和最小的割集。 可以用最小切割最大流定理: 1.min=MAXINT,確定一個源點 2.列舉匯點 3.計算最大流,並確定當前源匯的最小割集,若比

    先解釋下名詞的意思。 無向圖的割:就是去掉一些邊,使得原圖不連通,最小割就是要去掉邊的數量最小。 解決這個問題的常用辦法就是Stoer-Wagner 演算法; 先說下這個演算法的步驟後面給出證明: 1.min=MAXINT,固定一個頂點P 2.從點P用類似prim的

10.20校內測試模擬建樹判奇偶樹上差分

  Solution 和後面兩道題難度差距太大了吧!! 顯然就只是個小模擬,注意判0就行了。 Code #include<bits/stdc++.h> using namespace std; char s[100005]; int main() {