L3-007 天梯地图

参考自:https://blog.csdn.net/qq_21899803/article/details/63685476 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;

typedef long long ll;

const int maxn=509;
int head[maxn];

int top;
struct Edge{
	int v,w,next,h;
}edge[maxn*maxn];

void add(int u,int v,int w,int h){
	edge[top].v=v;
	edge[top].w=w;
	edge[top].h=h;
	edge[top].next=head[u];
	head[u]=top++;
}

void init(){
	top=0;
	memset(head,-1,sizeof(head));
}

priority_queue<pair<int,int> >q;

bool vis[maxn];

struct Node{
	int dis;
	int fa;
}a[maxn],b[maxn];//时间,长度; 
int dis[maxn];//求时间最短时需要考虑的相同时间路径最短; 

int st,en;
int n;
const int inf=0x3f3f3f3f;

vector<int>v1;//时间; 
vector<int>v2;

int vvv[maxn];//记录当前节点到st的最短路径的节点个数; 



void dij1(){//时间 
	memset(vis,0,sizeof(vis));
	//memset(a,0x3f,sizeof(a));
	for(int i=0;i<n;++i){
		a[i].dis=inf;
		a[i].fa=i;
	}
	
	for(int i=head[st];i!=-1;i=edge[i].next){
		int v=edge[i].v;
		dis[v]=edge[i].w;
	}
	
	dis[st]=0;
	a[st].dis=0;
	while(!q.empty()) q.pop();
	q.push(make_pair(0,st));
	while(!q.empty()){
		int u=q.top().second;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].v;
			int h=edge[i].h;
			if(a[v].dis>a[u].dis+h){
				a[v].dis=a[u].dis+h;
				dis[v]=dis[u]+edge[i].w;
				a[v].fa=u;
				q.push(make_pair(-a[v].dis,v));
			}
			else if(a[v].dis==a[u].dis+h){
				if(dis[v]>dis[u]+edge[i].w){
					a[v].fa=u;
					dis[v]=dis[u]+edge[i].w;
				}
			}
		}
	}
	int h=en;
	while(h!=st){
		v1.push_back(h);
		h=a[h].fa;
	}
	v1.push_back(st);
	
}


void dij2(){//长度; 
	memset(vis,0,sizeof(vis));
	for(int i=0;i<n;++i){
		vvv[i]=2;
		b[i].fa=i;
		b[i].dis=inf;
	}
	b[st].dis=0;
	vvv[st]=1;
	while(!q.empty()) q.pop();
	q.push(make_pair(0,st));
	while(!q.empty()){
		int u=q.top().second;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].v;
			int w=edge[i].w;
			if(b[v].dis>b[u].dis+w){
				b[v].dis=b[u].dis+w;
				b[v].fa=u;
				vvv[v]=vvv[u]+1;
				q.push(make_pair(-b[v].dis,v));
			}
			else if(b[v].dis==b[u].dis+w){
				if(vvv[v]>vvv[u]+1){
					b[v].fa=u;
					vvv[v]=vvv[u]+1;
				}
			}
		}
		
	}
	int h=en;
	while(h!=st){
		v2.push_back(h);
		h=b[h].fa;
	}
	v2.push_back(st);
}

bool check(){
	int x1=v1.size();
	int x2=v2.size();
	if(x1!=x2) return 0;
	for(int i=0;i<x1;++i)
		if(v1[i]!=v2[i]) return 0;
	return 1;
}

int main(){
	int m;
	init();
	int u,v,w,h;
	scanf("%d%d",&n,&m);
	int id;
	while(m--){
		scanf("%d%d%d%d%d",&u,&v,&id,&w,&h);
		add(u,v,w,h);
		if(!id) add(v,u,w,h);
	}
	scanf("%d%d",&st,&en);
	dij2();
	dij1();
	int x=v1.size();
	int y=v2.size();
	if(check()){
		
		printf("Time = %d; Distance = %d: ",a[en].dis,b[en].dis);
		printf("%d",v1[y-1]);
		for(int i=y-2;i>=0;--i)
			printf(" => %d",v1[i]);
		printf("\n");
	}
	else{//不同
		printf("Time = %d: ",a[en].dis);
		printf("%d",v1[x-1]);
		for(int i=x-2;i>=0;--i)
			printf(" => %d",v1[i]);
		printf("\n");
		printf("Distance = %d: ",b[en].dis);
		printf("%d",v2[y-1]);
		for(int i=y-2;i>=0;--i)
			printf(" => %d",v2[i]);
		printf("\n");
	}
	
	return 0;
}
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;

typedef long long ll;
const int maxn=509;
const int inf=0x3f3f3f3f;

int head[maxn];
int top;
struct Edge{
	int v,next;
	ll w,h;
}edge[maxn*maxn];


void init(){
	top=0;
	memset(head,-1,sizeof(head));
}

void add(int u,int v,ll w,ll h){
	edge[top].v=v;
	edge[top].w=w;
	edge[top].h=h;
	edge[top].next=head[u];
	head[u]=top++;
}

int fre_w[maxn],fre_h[maxn];

ll dis_w[maxn],dis_h[maxn];

ll dis[maxn];

int dian[maxn];

int vis[maxn];
int st,en;

priority_queue<pair<ll,int> >q;
vector<int>v1;//w
vector<int>v2;//h

void dij_w(){
	memset(dis_w,0x3f,sizeof(dis_w));
	dis_w[st]=0;
	memset(vis,0,sizeof(vis));
	while(!q.empty()) q.pop();
	q.push(make_pair(0,st));

	while(!q.empty()){
		int u=q.top().second; q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].v;
			ll w=edge[i].w;
			if(dis_w[v]>dis_w[u]+w){
				dis_w[v]=dis_w[u]+w;
				dian[v]=dian[u]+1;
				fre_w[v]=u;
				q.push(make_pair(-dis_w[v],v));
			}
			else if(dis_w[v]==dis_w[u]+w){
				if(dian[v]>dian[u]){
					fre_w[v]=u;
					dian[v]=dian[u]+1;
				}
			}
		}
	}
	int in=en;
	while(in!=st){
		v1.push_back(in);
		in=fre_w[in];
	}
	v1.push_back(st);
}

void dij_h(){
	memset(dis_h,0x3f,sizeof(dis_h));
	dis_h[st]=0;
	memset(vis,0,sizeof(vis));
	while(!q.empty()) q.pop();
	q.push(make_pair(0,st));
	
	memset(dis,0x3f,sizeof(dis));
	for(int i=head[st];i!=-1;i=edge[i].next){
		int v=edge[i].v;
		if(dis[v]>edge[i].w) dis[v]=edge[i].w;
	}
	
	while(!q.empty()){
		int u=q.top().second; q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i!=-1;i=edge[i].next){
			int v=edge[i].v;
			ll h=edge[i].h;
			if(dis_h[v]>dis_h[u]+h){
				dis_h[v]=dis_h[u]+h;
				fre_h[v]=u;
				dis[v]=dis[u]+edge[i].w;
				q.push(make_pair(-dis_h[v],v));
			}
			else if(dis_h[v]==dis_h[u]+h){
				if(dis[v]>dis[u]+edge[i].w){
					dis[v]=dis[u]+edge[i].w;
					fre_h[v]=u;
				}
			}
		}
	}
	int in=en;
	while(in!=st){
		v2.push_back(in);
		in=fre_h[in];
	}
	v2.push_back(st);
}

bool check(){
	int x=v1.size();
	int y=v2.size();
	if(x!=y) return 0;
	for(int i=0;i<x;++i)
		if(v1[i]!=v2[i]) return 0;
	return 1;
}

int main(){
	
	int n,m;
	init();
	scanf("%d%d",&n,&m);
	
	int u,v,w,h,id;
	
	while(m--){
		scanf("%d%d%d%d%d",&u,&v,&id,&w,&h);
		add(u,v,w,h);
		if(!id) add(v,u,w,h);
	}
	scanf("%d%d",&st,&en);
	dij_w();
	dij_h();
	int x=v1.size(),y=v2.size();//w,h;
	if(!check()){
		printf("Time = %lld: ",dis_h[en]);
		printf("%d",v2[y-1]);
		for(int i=y-2;i>=0;--i)
			printf(" => %d",v2[i]);
		printf("\n");
		printf("Distance = %lld: ",dis_w[en]);
		printf("%d",v1[x-1]);
		for(int i=x-2;i>=0;--i)
			printf(" => %d",v1[i]);
		printf("\n");
	}
	else{
		printf("Time = %lld; Distance = %lld: ",dis_h[en],dis_w[en]);
		printf("%d",v1[x-1]);
		for(int i=x-2;i>=0;--i)
			printf(" => %d",v1[i]);
		printf("\n");
		
		
	}
	
	return 0;
	
	
}

猜你喜欢

转载自blog.csdn.net/chenyume/article/details/88766870