PAT甲级专题|最短路
PAT甲级最短路
主要算法:dijkstra 求最短最长路、dfs图论搜索。
1018,dijkstra记录路径 + dfs搜索路径最值
25分,错误点暂时找不出。。
如果只用dijkstra没法做,只能得20分
#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 510;
int cmax,n,ter,m;
int caps[maxn];
int g[maxn][maxn];
int vis[maxn];
vector<int> pre[maxn];
int dist[maxn];
int half;
vector<int> paths;
vector<int> temp;
int minsend = inf;
int mintake = inf;
//dfs
void dfs(int x){
	temp.push_back(x);
	if(x == 0){
		int need = 0;
		int take = 0;
		for(int i=0;i<temp.size();i++){
			if(temp[i] == 0) continue;
			if(caps[temp[i]] - half > 0){
				int d = caps[temp[i]] - half;
				if(need >= d) need -= d;
				else{
					need = 0;
					take += (d - need);
				}
			}else{
				need += (half - caps[temp[i]]);
			}
		}
		if(need < minsend){
			minsend = need;
			mintake = take;
			paths = temp;
		}else if(need == minsend){
			if(mintake > take){
				mintake = take;
				paths = temp;
			}
		}
		temp.pop_back();
		return;
	}
	for(int i=0;i<pre[x].size();i++){
		dfs(pre[x][i]);
	}
	temp.pop_back();
}
void dijkstra(){
    memset(vis,0,sizeof(vis));
    memset(dist,inf,sizeof(dist));
    int half = cmax/2;
    dist[0] = 0;
    for(int i=0;i<=n;i++){
        int v,min_w = inf;
        for(int j=0;j<=n;j++){
            if(!vis[j] && dist[j] < min_w){
                min_w = dist[j];
                v = j;
            }
        }
        if(min_w == inf) return;
        vis[v] = 1;
        for(int j=0;j<=n;j++){
			if(vis[j] || g[v][j] == inf) continue;
			if(g[v][j] + dist[v] < dist[j]){
				dist[j] = g[v][j] + dist[v];
				pre[j].clear();
				pre[j].push_back(v);
			}else if(g[v][j] + dist[v] == dist[j]){
				pre[j].push_back(v);
			}
        }
    }
}
int main(){
	memset(g,inf,sizeof(g));
    cin>>cmax>>n>>ter>>m;
    half = cmax/2;
    caps[0] = 0;
    for(int i=1;i<=n;i++) cin>>caps[i];
    for(int i=1;i<=m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        g[u][v] = w;
        g[v][u] = w;
    }
    dijkstra();
	dfs(ter);
	cout<<minsend<<" ";
	for(int i=paths.size()-1;i>0;i--){
		cout<<paths[i]<<"->";
	}
	cout<<paths[0];
	cout<<" "<<mintake<<endl;
    return 0;
}
/*
10 3 3 5
6 7 10
0 1 1
0 2 1
0 3 2
1 3 1
2 3 1
*/
1030,多边权,多条更新
#include<bits/stdc++.h>
using namespace std;
/*
dijkstra:双边权
*/
const int inf = 0x3f3f3f3f;
const int maxn = 510;
int n,m,s,d;
int dist[maxn];
int path[maxn];
int cost[maxn];
int vis[maxn];
struct edge{
	int v,w,c;
	edge(int vv,int ww,int cc){
		v = vv;
		w = ww;
		c = cc;
	}
};
vector<int> paths;
vector<edge> g[maxn]; 
void dijkstra(int ss){
    memset(vis,0,sizeof(vis));
    memset(dist,inf,sizeof(dist));
    memset(cost,inf,sizeof(cost));
    dist[ss] = 0;
    cost[ss] = 0;
    path[ss] = -1;
    for(int i=0;i<n;i++){
        int v,min_w = inf;
        for(int j=0;j<n;j++){
            if(!vis[j] && dist[j] < min_w){
                min_w = dist[j];
                v = j;
            }
        }
        if(min_w == inf) return;
        vis[v] = 1;
        for(int j=0;j<g[v].size();j++){
            int x = g[v][j].v;
            if(!vis[x] && dist[v] + g[v][j].w < dist[x]){
            	cost[x] = cost[v] + g[v][j].c;
                dist[x] = dist[v] + g[v][j].w;
                path[x] = v;
            }else if(!vis[x] && dist[v] + g[v][j].w == dist[x]){
				if(cost[x] > cost[v] + g[v][j].c){
					path[x] = v;
					cost[x] = cost[v] + g[v][j].c;
				}
            }
        }
    }
}
int main(){
	cin>>n>>m>>s>>d;
	for(int i=1;i<=m;i++){
		int u,v,w,c;
		cin>>u>>v>>w>>c;
		g[u].push_back(edge(v,w,c));
		g[v].push_back(edge(u,w,c));
	}
	dijkstra(s);
	int cur = d;
	while(cur != -1){
		paths.push_back(cur);
		cur = path[cur];
	}
	for(int i=paths.size()-1;i>=0;i--){
		cout<<paths[i]<<" ";
	}
	cout<<dist[d]<<" "<<cost[d]<<endl;
	return 0;
}
1087,记录所有路径,dfs搜索路径最值
#include<bits/stdc++.h>
using namespace std;
/*
map映射:string <-> cityId  Name <-> Int
dijkstra:找出最短路的长度 以及所有最短路径(存入到pre容器中)
dfs:统计最短路的数量 从终点触发在出口判断更新所需的权值
*/
const int inf = 0x3f3f3f3f;
const int maxn = 210;
map<string, int> mp;
map<int,string> mp2;
int n,k;
string start;
int haps[maxn];
int g[maxn][maxn];
int nums;
int vis[maxn];
int dist[maxn];
int ter = 0;
vector<int> pre[maxn];
vector<int> temp,path;
int maxhap = 0;
double maxave = 0;
void dfs(int x){
	temp.push_back(x);
	if(x == n){
		int curhap = 0;
		double curave = 0;
		for(int i=temp.size()-1;i>=0;i--){
			curhap += haps[temp[i]];
		}
		if(temp.size() == 1){
			curave = 0;
		}else{
			curave = curhap*1.0/(temp.size()-1);
		}
		if(maxhap < curhap){
			maxhap = curhap;
			maxave = curave;
			path = temp;
		}else if(maxhap == curhap){
			if(maxave < curave){
				maxave = curave;
				path = temp;
			}
		}
		nums++;
		temp.pop_back();
		return;
	}
	for(int i=0;i<pre[x].size();i++){
		dfs(pre[x][i]);
	}
	temp.pop_back();
}
void dijkstra(int s){
    memset(vis,0,sizeof(vis));
    memset(dist,inf,sizeof(dist));
    dist[s] = 0;
    for(int i=1;i<=n;i++){
        int v,min_w = inf;
        for(int j=1;j<=n;j++){
            if(!vis[j] && dist[j] < min_w){
                v = j;
                min_w = dist[j];
            }
        }
        vis[v] = 1;
        if(min_w == inf) return;
        for(int j=1;j<=n;j++){
            if(!vis[j] && g[v][j] != inf){
                if(dist[j] > dist[v] + g[v][j]){
                	dist[j] = dist[v] + g[v][j];
                	pre[j].clear();
                	pre[j].push_back(v);
                }else if(dist[j] == dist[v] + g[v][j]){
                	pre[j].push_back(v);
                }
            }
        }
    }
}
int main(){
    memset(g,inf,sizeof(g));
    cin>>n>>k>>start;
    for(int i=1;i<=n-1;i++){
        string city;
        int hap;
        cin>>city>>hap;
        mp[city] = i;
        mp2[i] = city;
        haps[i] = hap;
    }
    mp[start] = n;
    mp2[n] = start;
    haps[n] = 0;
    for(int i=1;i<=k;i++){
        string c1,c2;
        int cost;
        cin>>c1>>c2>>cost;
        int u = mp[c1];
        int v = mp[c2];
        g[u][v] = cost;
        g[v][u] = cost;
    }
    ter = mp["ROM"];
    dijkstra(n);
    dfs(ter);
    cout<<nums<<" "<<dist[ter]<<" "<<maxhap<<" "<<int(maxave)<<endl;
    cout<<start;
    for(int i=path.size()-2;i>0;i--){
    	cout<<"->"<<mp2[path[i]];
	}
	cout<<"->ROM"<<endl;
    return 0;
}
1111,多边权、记录路径、多条件更新
#include<bits/stdc++.h>
using namespace std;
/*
30分
*/
const int inf = 0x3f3f3f3f;
const int maxn = 510;
int source,ter;
int n,m;
int vis1[maxn];
int vis2[maxn];
struct edge{
    int v;
    int length;
    int time;
    edge(int vv,int len,int ti){
        v = vv;
        length = len;
        time = ti;
    }
};
vector<edge> g[maxn];
int dist1[maxn];
int time1[maxn];
int time2[maxn];
int path1[maxn];
int path2[maxn];
int nums[maxn];
vector<int> ans1;
vector<int> ans2;
void dijkstra1(){
    memset(vis1,0,sizeof(vis1));
    memset(dist1,inf,sizeof(dist1));
    memset(time1,inf,sizeof(time1));
    dist1[source] = 0;
    time1[source] = 0;
    path1[source] = -1;
    for(int i=0;i<n;i++){
        int v,min_w = inf;
        for(int j=0;j<n;j++){
            if(!vis1[j] && dist1[j] < min_w){
                v = j;
                min_w = dist1[j];
            }
        }
        vis1[v] = 1;
        if(min_w == inf) return;
        for(int j=0;j<g[v].size();j++){
            int u = g[v][j].v;
            if(!vis1[u]){
                if(dist1[u] > dist1[v] + g[v][j].length){
                    time1[u] = time1[v] + g[v][j].time;
                    dist1[u] = dist1[v] + g[v][j].length;
                    path1[u] = v;
                }else if(dist1[u] == dist1[v] + g[v][j].length && time1[u] > time1[v] + g[v][j].time){
                    time1[u] = time1[v] + g[v][j].time;
                    path1[u] = v;
                }
            }
        }
    }
}
void dijkstra2(){
    memset(vis2,0,sizeof(vis2));
    memset(nums,inf,sizeof(nums));
    memset(time2,inf,sizeof(time2));
    nums[source] = 1;
    time2[source] = 0;
    path2[source] = -1;
    for(int i=0;i<n;i++){
        int v,min_w = inf;
        for(int j=0;j<n;j++){
            if(!vis2[j] && time2[j] < min_w){
                v = j;
                min_w = time2[j];
            }
        }
        vis2[v] = 1;
        if(min_w == inf) return;
        for(int j=0;j<g[v].size();j++){
            int u = g[v][j].v;
            if(!vis2[u]){
                if(time2[u] > time2[v] + g[v][j].time){
                    time2[u] = time2[v] + g[v][j].time;
                    nums[u] = nums[v] + 1;
                    path2[u] = v;
                }else if(time2[u] == time2[v] + g[v][j].time){
                    if(nums[u] >= nums[v] + 1){
                        path2[u] = v;
                        nums[u] = nums[v] + 1;
                    }
                }
            }
        }
    }
}
bool identical(){
    int cur = ter;
    while(cur != -1){
        ans1.push_back(cur);
        cur = path1[cur];
    }
    cur = ter;
    while(cur != -1){
        ans2.push_back(cur);
        cur = path2[cur];
    }
    reverse(ans1.begin(),ans1.end());
    reverse(ans2.begin(),ans2.end());
    if(ans1.size() != ans2.size()) return false;
    for(int i=0;i<ans1.size();i++){
        if(ans1[i] != ans2[i])return false;
    }
    return true;
}
int main(){
//	freopen("in.txt", "r", stdin);
//	freopen("out.txt", "w", stdout);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int v1,v2,one,length,time;
        cin>>v1>>v2>>one>>length>>time;
        if(one == 0){
            g[v1].push_back(edge(v2,length,time));
            g[v2].push_back(edge(v1,length,time));
        }else{
            g[v1].push_back(edge(v2,length,time));
        }
    }
    cin>>source>>ter;
    dijkstra1();
    dijkstra2();
    if(identical()){
        printf("Distance = %d; Time = %d: %d",dist1[ter],time2[ter],source);
        for(int i=1;i<ans1.size();i++){
            printf(" -> %d",ans1[i]);
        }
        printf("\n");
    }else{
        printf("Distance = %d: %d",dist1[ter],source);
        for(int i=1;i<ans1.size();i++){
            printf(" -> %d",ans1[i]);
        }
        printf("\n");
        printf("Time = %d: %d",time2[ter],source);
        for(int i=1;i<ans2.size();i++){
            printf(" -> %d",ans2[i]);
        }
        printf("\n");
    }
    return 0;
}
/*
4 4
0 1 1 1 2
0 2 1 2 1
1 3 1 2 2
2 3 1 1 1
0 3
*/
PAT甲级专题|最短路的更多相关文章
- PAT甲级专题|树的遍历
		PAT甲级专题-树的遍历 涉及知识点:树.建树.深度优先搜索.广度优先搜索.递归 甲级PTA 1004 输出每一层的结点,邻接表vector建树后.用dfs.bfs都可以边搜边存当前层的数据, #in ... 
- PAT甲级专题|链表
		PAT链表专题 关于PAT甲级的链表问题,主要内容 就是"建立链表" 所以第一步学会模拟链表,pat又不卡时间,这里用vector + 结构体,更简洁 模拟链表的普遍代码 cons ... 
- PAT甲级满分攻略|记一次考试经历
		一次考试经历 今天是"大雪",很冷. 来到隔壁的学校考试,记得上一次来河中医是两年前大一刚开学吧,那天晚上印象比较深刻,6个室友骑车到处闲逛.当时还不会Hello world. 很 ... 
- PAT甲级题解(慢慢刷中)
		博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6102219.html特别不喜欢那些随便转载别人的原创文章又不给 ... 
- PAT甲级1131. Subway Map
		PAT甲级1131. Subway Map 题意: 在大城市,地铁系统对访客总是看起来很复杂.给你一些感觉,下图显示了北京地铁的地图.现在你应该帮助人们掌握你的电脑技能!鉴于您的用户的起始位置,您的任 ... 
- 【转载】【PAT】PAT甲级题型分类整理
		最短路径 Emergency (25)-PAT甲级真题(Dijkstra算法) Public Bike Management (30)-PAT甲级真题(Dijkstra + DFS) Travel P ... 
- 图论 - PAT甲级 1003 Emergency C++
		PAT甲级 1003 Emergency C++ As an emergency rescue team leader of a city, you are given a special map o ... 
- 2019秋季PAT甲级_备考总结
		2019 秋季 PAT 甲级 备考总结 在 2019/9/8 的 PAT 甲级考试中拿到了满分,考试题目的C++题解记录在这里,此处对备考过程和考试情况做一个总结.如果我的方法能帮助到碰巧点进来的有缘 ... 
- PAT甲级题分类汇编——序言
		今天开个坑,分类整理PAT甲级题目(https://pintia.cn/problem-sets/994805342720868352/problems/type/7)中1051~1100部分.语言是 ... 
随机推荐
- [2018-01-13] 安装Django的一些笔记
			安装django pip install Django = =1.10.2 下载源码,进入根目录执行 python setup.py install 确认是否已经安装成功 python -m djan ... 
- Docker的centos7容器中如何安装mongodb
			下载安装包: wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.12.tgz 解压安装包 tar -zxvf mongodb ... 
- LeetCode刷题总结-数组篇(下)
			本期讲O(n)类型问题,共14题.3道简单题,9道中等题,2道困难题.数组篇共归纳总结了50题,本篇是数组篇的最后一篇.其他三个篇章可参考: LeetCode刷题总结-数组篇(上),子数组问题(共17 ... 
- 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(3) - 使用Conductor切换页面
			前两章中, 我们已经实现了这个图书管理系统的登录窗口, 并实施了完善的单元测试. 该是时候回过头来关注我们的主窗口了. 一个功能丰富的系统一般会有多个页面, 我们图书管理系统虽然是"简易&q ... 
- python基础-面向过程编程
			面向过程编程 面向过程编程其实是一种机械式的思维方式,其核心就是"过程". 过程指的是一种解决问题的步骤,即先干什么再干什么,最后干什么. 优点:将复杂的问题流程化,进而简单化. ... 
- egret编译速度慢解决方法
			egret编译速度慢解决方法 直接用增量更新egret run -a 每次改完代码 保存都会自动编译 
- Spring中常用的注解及作用
			@Component(value) 配置类,当使用该注解时,SpringIOC会将这个类自动扫描成一个bean实例 不写的时候,默认是类名,且首字母小写 @ComponentScan 默认是代表进行扫 ... 
- dubbo中出现can not be invoked any more
			具体错误示例如下 从错误看,是客户方发起调用时,dubbo会去检查本地的invoker instance,如果发现invoker已经是destroy status,则直接抛出上面的异常,下面先来说下平 ... 
- React组件间的通讯
			组件化开发应该是React核心功能之一,组件之间的通讯也是我们做React开发必要掌握的技能.接下来我们将从组件之间的关系来分解组件间如何传递数据. 1.父组件向子组件传递数据 通讯是单向的,数据必须 ... 
- Linux定时任务 crontab(-l -e)、at、batch
			1.周期性定时任务crontab cron['krɒn] 一时间单位 table crontab -e 进入编辑定时任务界面,每一行代表一个定时任务,#开头的行为注释行,一行分成6列 分钟 小时 日 ... 
