jzoj 1267. 路障(block.pas/c/cpp)

Description
  Bessie 來到一個小農場,有時她想回老家看看她的一位好友。她不想太早地回到老家,因爲她喜歡途中的美麗風景。她決定選擇次短路徑,而不是最短路徑。
  農村有 R (1 <= R <= 100,000) 條雙向的路,每條路連接 N (1 <= N <= 5000) 個結點中的兩個。結點的編號是 1…N。Bessie 從結點 1出發,她的朋友(目的地)在結點 N。
  次短路徑可以使用最短路徑上的路,而且允許退回,即到達一個結點超過一次。次短路徑是一種長度大於最短路徑的路徑(如果存在兩條或多條最短路徑存在,次短路徑就是比它們長,且不比其他任何的路徑長的路徑)。

Input
  Line 1: 兩個用空格分隔的整數 N 和 R
  Lines 2…R+1: 每行包含三個用空格分隔的整數: A, B, 和 D表示有一條路連接結點A和B,長度爲D (1 <= D <= 5000)。

Output
  Line 1: 結點 1 到結點 N的次短路徑長度。

Sample Input
4 4
1 2 100
2 4 200
2 3 250
3 4 100

Sample Output
450

Data Constraint

Hint
【樣例說明】
兩條路徑: 1 -> 2 -> 4 (長度 100+200=300) 以及 1 -> 2 -> 3 -> 4(長度 100+250+100=450)

//written by zzy

題目大意:

求一個圖的次短路

題解:

跑兩邊spfa,處理出 11 號點 和 nn 號點到所有點的單源最短路 d1,dnd1,dn
再枚舉每條邊 (u,v)(u,v) ,用 11uuvvnn 的長度更新答案

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#define N 5005
#define M 100005
#define Max 1000000007
using namespace std;

int i,j,n,m,p,a,b,c,ans;
int d1[N],dn[N];
bool vis[N];

int next[2*M],list[N],u[2*M],v[2*M],z[2*M];

queue<int> q;

void add(int x) {
	next[++p]=list[x];
	list[x]=p;
}

void spfa1() {
	for (i=1;i<=n;i++) d1[i]=Max;
	d1[1]=0;
	q.push(1);
	while (q.size()!=0) {
		int x=q.front();
		for (int t=list[x],to=v[t];t;t=next[t],to=v[t]) {
			if (d1[x]+z[t]<d1[to]) {
				d1[to]=d1[x]+z[t];
				if (!vis[to]) 
			     vis[to]=true,q.push(to);
			} 
		}
		vis[x]=false,q.pop();
	}
}

void spfa_n() {
	for (i=1;i<=n;i++) dn[i]=Max;
	dn[n]=0;
	q.push(n);
	while (q.size()!=0) {
		int x=q.front();
		for (int t=list[x],to=v[t];t;t=next[t],to=v[t]) {
			if (dn[x]+z[t]<dn[to]) {
				dn[to]=dn[x]+z[t];
				if (!vis[to]) 
			     vis[to]=true,q.push(to);
			} 
		}
		vis[x]=false,q.pop();
	}
}

int main()
{
	scanf("%d%d",&n,&m);
	for (i=1;i<=m;i++) {
		scanf("%d%d%d",&a,&b,&c);
		add(a); u[i*2-1]=a,v[i*2-1]=b,z[i*2-1]=c;
		add(b); u[i*2]=b,v[i*2]=a,z[i*2]=c;
	}
	spfa1();
	spfa_n();
	ans=Max;
	for (i=1;i<=2*m;i++)
	 if (d1[u[i]]+z[i]+dn[v[i]]>d1[n])
	  ans=min(ans,d1[u[i]]+z[i]+dn[v[i]]);
	printf("%d",ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章