lightOJ 1002 country roads (最短路算法的拓展變式)

lightOJ 1002 Country Roads

單源最長路徑怎麼求 ?當然就是把單源最短路徑改過來就行了.

那麼,其他涉及邊的狀態轉移的問題呢?是否也能用最短路算法魔改而成?答案是肯定的.

題目大意

給定一張無向圖和一個終點,定義一個點到終點的權爲這個點到終點的所有路徑中長度最大的邊的最小值.

如圖,點0到4的路徑有三條,它們的路徑上的邊權最大值分別是8,9,7,取最小,輸出7

題目分析

涉及邊之間狀態的轉移,前後狀態又互相有關聯,顯然可以用最短路算法的拓展變式求解.

而我們知道,狀態轉移通過鬆弛實現.

爲了表示這種狀態的轉移,我們不妨分析一下這個最小值是怎麼通過鬆弛得到的,以得到鬆弛的實現思路.

在這裏插入圖片描述
原始圖

ss點爲最終要到達的點,由於是無向圖,所以從它開始做最短路(倒着路徑訪問順序求所求邊)也是沒問題的.


在這裏插入圖片描述

第一次鬆弛之後

lenlen表示當前點到ss點的路徑的所求邊.


在這裏插入圖片描述
第二次鬆弛(1)

現在kkss的所求邊爲len=max(8,10)=10len=max(8,10)=10

在這裏插入圖片描述

第二次鬆弛(2)

現在kkss的所求邊爲len=min(len,max(2,7))=7len=min(len,max(2,7))=7


那麼,我們就可以得到鬆弛時的操作:

1.若當前節點沒有len,那麼len=max(len[u],e.w)
2.否則當前節點的len=min(len,max(len[u],e.w))
其中u是前一個節點,e.w是u到當前節點的邊權

全題就解決了.

程序實現

#include<bits/stdc++.h>
#define maxn 50010
using namespace std;
struct edge{
	int next,v,w;
}e[maxn];
int head[510],tot;
void add(int u,int v,int w){
	e[++tot].v =v;
	e[tot].w =w;
	e[tot].next =head[u];
	head[u]=tot;
}
int n,m,s;
bool vis[510];
int len[510];
void spfa(){
	memset(len,-1,sizeof len);//-1爲初始狀態
	memset(vis,false,sizeof vis);
	queue<int >q;
	q.push(s);
	vis[s]=true;
	len[s]=0;
	while(!q.empty()){
		int u=q.front();
		for(int i=head[u];i;i=e[i].next ){
			int v=e[i].v ;
			if(len[v]==-1){
				len[v]=max(len[u],e[i].w );
				vis[v]=true;
				q.push(v);
			}//如果還是初始狀態,直接更新
			if(len[v]>max(len[u],e[i].w )){
				len[v]=max(len[u],e[i].w );
				if(!vis[v]){
					vis[v]=true;
					q.push(v);
				}//否則進行比較然後視情況鬆弛
			}
		}
		vis[u]=false;
		q.pop();
	}
}
int main(){
	int T;
	scanf("%d",&T);
	for(int ab=1;ab<=T;ab++){
	memset(e,0,sizeof e);
	memset(head,0,sizeof head);//初始化
	tot=0;
	scanf("%d%d",&n,&m);
	for(int i=1,u,v,w;i<=m;i++){
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		add(v,u,w);//無向圖
	}
	scanf("%d",&s);
	spfa();
	printf("Case %d:\n",ab);
	for(int i=0;i<n;i++){
		if(len[i]==-1)printf("Impossible\n");
		else printf("%d\n",len[i]);
	}}
	return 0;
}

題後總結

由於各種最短路算法,實際上都是邊之間的狀態轉移,所以所有涉及邊之間狀態轉移(前後狀態有關聯)的有關圖的問題,都可以在最短路算法的基礎上加以修改,從而得解.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章