zoukankan      html  css  js  c++  java
  • PAT 甲级 1111 Online Map (30 分)

    思路:

    1.两次dijskra即可,用dfs会超时,我剪枝剪了好久还是会超时…
    2.每次判断是否最短(最快)的时候依据题目中的两个标准;
    3.用vector保存每个点可达的下一个点,用邻接矩阵存储距离和时间,用数组标记每个点是否已知最短(最快),用数组记录每个点此刻离起点的距离、最短路径的最短可达时间、最短时间、最短时间的最少周转次数,再用数组保存每个点的最短路径前驱结点和最短时间前驱结点;
    4.用递归根据前驱结点数组来写vector;
    5.最后判断两个vector是否相等,根据题意输出即可;

    代码:

    #include<iostream>
    #include<vector>
    #include<climits>
    #include<map>
    #include<vector>
    using namespace std;
    int n,m,pos,des;
    int vlen[500][500],vt[500][500];
    vector<int> isknown(500),len(500),tlen(500),t(500),cnt(500),lenpre(500),tpre(500);
    map<int,vector<int>> mp;
    vector<int> lenpath,tpath;
    void dijDistance(int node){
    	isknown[node]=true;
    	for(auto e:mp[node]){
    		if(!isknown[e]){
    			int a=len[node]+vlen[node][e],b=tlen[node]+vt[node][e];
    			if(a<len[e]||(a==len[e]&&b<tlen[e])){
    				if(a<len[e]) len[e]=a;
    				tlen[e]=b;
    				lenpre[e]=node;
    			}
    		}
    	}
    	int temp;
    	for(temp=0;isknown[temp];temp++);
    	for(int i=temp;i<n;i++){
    		if(!isknown[i]&&(len[i]<len[temp]||(len[i]==len[temp]&&tlen[i]<tlen[temp])))
    			temp=i;
    	}
    	if(temp==des) return;
    	dijDistance(temp);
    }
    void dijTime(int node){
    	isknown[node]=true;
    	for(auto e:mp[node]){
    		if(!isknown[e]){
    			int a=t[node]+vt[node][e],b=cnt[node]+1;
    			if(a<t[e]||(a==t[e]&&b<cnt[e])){
    				if(a<t[e]) t[e]=a;
    				cnt[e]=b;
    				tpre[e]=node;
    			}
    		}
    	}
    	int temp;
    	for(temp=0;isknown[temp];temp++);
    	for(int i=temp;i<n;i++){
    		if(!isknown[i]&&(t[i]<t[temp]||(t[i]==t[temp]&&cnt[i]<cnt[temp])))
    			temp=i;
    	}
    	if(temp==des) return;
    	dijTime(temp);
    }
    void lenPathPrint(int node){
    	if(node!=pos) lenPathPrint(lenpre[node]);
    	lenpath.push_back(node);
    }
    void tPathPrint(int node){
    	if(node!=pos) tPathPrint(tpre[node]);
    	tpath.push_back(node);
    }
    int main(){	
    	scanf("%d%d",&n,&m);
    	for(int i=0;i<m;i++){
    		int v1,v2,oneway;
    		scanf("%d%d%d",&v1,&v2,&oneway);
    		scanf("%d%d",&vlen[v1][v2],&vt[v1][v2]);
    		mp[v1].push_back(v2);
    		if(!oneway){
    			vlen[v2][v1]=vlen[v1][v2];
    			vt[v2][v1]=vt[v1][v2];
    			mp[v2].push_back(v1);
    		}
    	}
    	scanf("%d%d",&pos,&des);
    	fill(isknown.begin(),isknown.end(),false);
    	fill(cnt.begin(),cnt.end(),INT_MAX);
    	len=tlen=t=cnt;
    	len[pos]=tlen[pos]=t[pos]=cnt[pos]=0;
    	dijDistance(pos);
    	fill(isknown.begin(),isknown.end(),false);
    	dijTime(pos);
    	lenPathPrint(des);
    	tPathPrint(des);
    	if(lenpath==tpath) printf("Distance = %d; Time = %d: %d",len[des],t[des],pos);
    	else{
    		printf("Distance = %d: %d",len[des],pos);
    		for(int i=1;i<lenpath.size();i++) printf(" -> %d",lenpath[i]);
    		printf("
    Time = %d: %d",t[des],pos);
    	}
    	for(int i=1;i<tpath.size();i++) printf(" -> %d",tpath[i]);
    	return 0;
    }
    
  • 相关阅读:
    ISO/IEC 9899:2011 条款6.6——常量表达式
    ISO/IEC 9899:2011 条款6.5.17——逗号操作符
    ISO/IEC 9899:2011 条款6.5.16——赋值操作符
    ISO/IEC 9899:2011 条款6.5.15——条件操作符
    ISO/IEC 9899:2011 条款6.5.10——按位与操作符
    ISO/IEC 9899:2011 条款6.5.9——相等操作符
    php正则表达式入门-常用语法格式
    史上最全PHP正则表达式实例汇总
    mysql数据库TINYINT取值范围详解
    Sql Server删除数据表中重复记录 三种方法
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12309003.html
Copyright © 2011-2022 走看看