PAT A1111 Online Map

题目难度:三颗半星
题目大意:给出一个图,其中有单向的路,有长度和时间的边权,然后需要给出长度和时间最小的路径,如果相同就输出一个就可以。
题目坑点:两次调用Dijkstra,最后需要进行比较求出的最小的条件路径两个方案是否相等,如果相等就输出一个,如果不等就分别输出,这个是一个同学刷到了,然后问我测试点三过不去,但是我提交了就过了啊 ,,,不知道他为啥测试点三不过。
代码如下:

#include<iostream>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<algorithm>
#include<map>
#include<cstring>
#define MAX 500
#define INF 0x3fffffff
using namespace std;
typedef struct{
	vector<int> path;
	int tcost,lcost;
}Method;
int vis[MAX],Dis[MAX][MAX],Time[MAX][MAX];
vector<Method> DisMethod;
vector<Method> TimeMethod;
vector<Method> tempMethod;
vector<int> pre[MAX];
vector<int> tempPath;
int N,M,start,ed;
bool cmp_dis(Method a,Method b){
	return a.tcost<b.tcost;
}
bool cmp_time(Method a,Method b){
	return a.path.size()<b.path.size();
}
void DFS(int n){
	if(n==start){
		tempPath.push_back(n);
		int tsum=0,lsum=0;
		for(int i=tempPath.size()-1;i>0;i--){
			tsum+=Time[tempPath[i]][tempPath[i-1]];
			lsum+=Dis[tempPath[i]][tempPath[i-1]];
		}
		Method m;
		m.path=tempPath;
		m.lcost=lsum;
		m.tcost=tsum;
		tempMethod.push_back(m);
		tempPath.pop_back();
		return;
	}
	tempPath.push_back(n);
	for(int i=0;i<pre[n].size();i++)
		DFS(pre[n][i]);
	tempPath.pop_back();
}
void Dijkstra(int s,int e,int d[],int G[MAX][MAX]){
	fill(vis,vis+MAX,0);
	d[s]=0;//因为默认从0开始 
	for(int i=0;i<=N;i++){
		int u=-1,minpath=INF;
		for(int j=0;j<N;j++){
			if(vis[j]==0&&d[j]<minpath){
				u=j;
				minpath=d[j];
			}
		}
		if(u==-1)
			break;
		vis[u]=1;
		for(int j=0;j<N;j++){
			if(vis[j]==0&&G[u][j]!=INF){
				if(d[j]>d[u]+G[u][j]){
					d[j]=d[u]+G[u][j];
					pre[j].clear();
					pre[j].push_back(u);
				}
				else if(d[j]==d[u]+G[u][j]){
					pre[j].push_back(u);
				}
			}
		}
	}
	tempMethod.clear();
	DFS(e);
}
int main(){
	int dis[MAX],time[MAX];
	fill(Dis[0],Dis[0]+MAX*MAX,INF);
	fill(Time[0],Time[0]+MAX*MAX,INF);
	fill(dis,dis+MAX,INF);
	fill(time,time+MAX,INF);
	cin>>N>>M;
	int V1,V2,isOne,length,time_in;
	for(int i=0;i<M;i++){
		cin>>V1>>V2>>isOne>>length>>time_in;
		Dis[V1][V2]=length;
		Time[V1][V2]=time_in;
		if(isOne==0){
			Dis[V2][V1]=length;
			Time[V2][V1]=time_in;
		}
	}
	cin>>start>>ed;
	Dijkstra(start,ed,dis,Dis);
	DisMethod=tempMethod;
	sort(DisMethod.begin(),DisMethod.end(),cmp_dis);
	Dijkstra(start,ed,time,Time);
	TimeMethod=tempMethod;
	sort(TimeMethod.begin(),TimeMethod.end(),cmp_time);
	Method l,t;
	l=DisMethod[0];
	t=TimeMethod[0];
	int flag=1;
	if(l.path.size()!=t.path.size())
		flag=0;
	for(int i=0;i<l.path.size();i++){
		if(l.path[i]!=t.path[i]){
			flag=0;
			break;
		}
	}
	if(flag==0){
		cout<<"Distance = "<<l.lcost<<":";
		for(int i=l.path.size()-1;i>=0;i--){
			cout<<" "<<l.path[i];
			if(i!=0)
				cout<<" ->";
		}
		cout<<endl;
		cout<<"Time = "<<t.tcost<<":";
		for(int i=t.path.size()-1;i>=0;i--){
			cout<<" "<<t.path[i];
			if(i!=0)
				cout<<" ->";
		}
	}
	else{
		cout<<"Distance = "<<l.lcost<<"; Time = "<<l.tcost<<":";
		for(int i=l.path.size()-1;i>=0;i--){
			cout<<" "<<l.path[i];
			if(i!=0)
				cout<<" ->";
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值