其他分享
首页 > 其他分享> > [tyvj 1450] GF打Dota {次短路}

[tyvj 1450] GF打Dota {次短路}

作者:互联网

题目

http://www.joyoi.cn/problem/tyvj-1450

题目大意

求最短路和次短路


解题思路

p=1p=1p=1时,显然是最短路。
p=2p=2p=2时:

首先以1和n为起点做一遍单源最短路,然后枚举每一条边(x,y),求出起点到x+终点到y+边(x,y)权值之和,若不等于1~n最短路长度则更新ans。
预期得分100分


代码

#include<cstdio>
#include<queue>
#include<string>
#include<cstring>
#define rr register 
using namespace std;
const int N=10010,M=50001; 
bool vis[N],p; 
int n,m,cnt,head[N],dis[N],pre[N],ans=2147483647; 
queue<int> q;   
struct node{
	int x,y,z,next; 
}a[M<<1];
void add(int x,int y,int z){a[++cnt]=(node){x,y,z,head[x]}; head[x]=cnt;}
int read(){
	int p=0; char c=getchar(); 
	while (!isdigit(c)) c=getchar(); 
	while (isdigit(c)) p=(p<<3)+(p<<1)+c-48,c=getchar(); 
	return p; 
}
void spfa(){
	memset(dis,127/2,sizeof(dis)); 
	q.push(1); 
	vis[1]=1; dis[1]=0; 
	while (!q.empty()){
		int x=q.front(); q.pop(); 
		for (rr  int i=head[x];i;i=a[i].next){
			int y=a[i].y; 
			if (a[i].z+dis[x]<dis[y]) {
				dis[y]=dis[x]+a[i].z; 
				if (!vis[y]) q.push(y),vis[y]=1; 
			}
		}
		vis[x]=0; 
	}
}
void spfaa(){
	memset(pre,127/2,sizeof(pre)); 
	q.push(n); 
	vis[n]=1; pre[n]=0; 
	while (!q.empty()){
		int x=q.front(); q.pop(); 
		for (rr int i=head[x];i;i=a[i].next){
			int y=a[i].y; 
			if (a[i].z+pre[x]<pre[y]) {
				pre[y]=pre[x]+a[i].z; 
				if (!vis[y]) q.push(y),vis[y]=1; 
			}
		}
		vis[x]=0; 
	}
}
int main(){
	n=read(),m=read(); 
	int x,y,z; 
	for (rr int i=1;i<=m;i++){
		x=read(),y=read(),z=read(); 
		add(x,y,z),add(y,x,z); 
	}
	p=read(); 
	spfa(); spfaa(); 
	if (p==0) return 0&printf("%d",dis[n]);
	for (rr int i=1;i<=cnt;i++){
		int x=a[i].x,y=a[i].y;
		int e=dis[x]+pre[y]+a[i].z; 
		if (e!=dis[n]&&e<ans) ans=e; 
	}
	printf("%d",ans); 
}

标签:1p,tyvj,int,短路,GF,Dota,1450,ans,include
来源: https://blog.csdn.net/qq_39897867/article/details/88075898