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甲级专题|最短路的更多相关文章

  1. PAT甲级专题|树的遍历

    PAT甲级专题-树的遍历 涉及知识点:树.建树.深度优先搜索.广度优先搜索.递归 甲级PTA 1004 输出每一层的结点,邻接表vector建树后.用dfs.bfs都可以边搜边存当前层的数据, #in ...

  2. PAT甲级专题|链表

    PAT链表专题 关于PAT甲级的链表问题,主要内容 就是"建立链表" 所以第一步学会模拟链表,pat又不卡时间,这里用vector + 结构体,更简洁 模拟链表的普遍代码 cons ...

  3. PAT甲级满分攻略|记一次考试经历

    一次考试经历 今天是"大雪",很冷. 来到隔壁的学校考试,记得上一次来河中医是两年前大一刚开学吧,那天晚上印象比较深刻,6个室友骑车到处闲逛.当时还不会Hello world. 很 ...

  4. PAT甲级题解(慢慢刷中)

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6102219.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  5. PAT甲级1131. Subway Map

    PAT甲级1131. Subway Map 题意: 在大城市,地铁系统对访客总是看起来很复杂.给你一些感觉,下图显示了北京地铁的地图.现在你应该帮助人们掌握你的电脑技能!鉴于您的用户的起始位置,您的任 ...

  6. 【转载】【PAT】PAT甲级题型分类整理

    最短路径 Emergency (25)-PAT甲级真题(Dijkstra算法) Public Bike Management (30)-PAT甲级真题(Dijkstra + DFS) Travel P ...

  7. 图论 - PAT甲级 1003 Emergency C++

    PAT甲级 1003 Emergency C++ As an emergency rescue team leader of a city, you are given a special map o ...

  8. 2019秋季PAT甲级_备考总结

    2019 秋季 PAT 甲级 备考总结 在 2019/9/8 的 PAT 甲级考试中拿到了满分,考试题目的C++题解记录在这里,此处对备考过程和考试情况做一个总结.如果我的方法能帮助到碰巧点进来的有缘 ...

  9. PAT甲级题分类汇编——序言

    今天开个坑,分类整理PAT甲级题目(https://pintia.cn/problem-sets/994805342720868352/problems/type/7)中1051~1100部分.语言是 ...

随机推荐

  1. Cookie、Session、Token那点事儿

    1.什么是Cookie? Cookie 技术产生源于 HTTP 协议在互联网上的急速发展.随着互联网时代的策马奔腾,带宽等限制不存在了,人们需要更复杂的互联网交互活动,就必须同服务器保持活动状态(简称 ...

  2. Kong06-Kong 的集群怎么用

    Kong 集群允许您通过添加更多的机器来处理更多的传入请求来横向扩展系统.它们将共享相同的配置,因为它们指向相同的数据库.指向相同数据存储的 Kong 节点将属于相同的 Kong 集群. 您需要在Ko ...

  3. CSPS模拟 93

    恰饭的时候lsc说我颓颓废废是要ak的前兆 所以我rp掉光了=.= T1 思维一片混乱 T2 只会n^3 发现决策单调性,但没想全 只知道$determin(l,r)>=determin(l,r ...

  4. 死磕 java线程系列之终篇

    (手机横屏看源码更方便) 简介 线程系列我们基本就学完了,这一个系列我们基本都是围绕着线程池在讲,其实关于线程还有很多东西可以讲,后面有机会我们再补充进来.当然,如果你有什么好的想法,也可以公从号右下 ...

  5. python基础-闭包函数和装饰器

    闭包函数和装饰器 闭包函数 概念:在函数中(嵌套)定义另一个函数时,内部函数引用了外层函数的名字. 特性 闭包函数必须在函数内部定义 闭包函数可引用外层函数的名字 闭包函数是函数嵌套.函数对象.名称空 ...

  6. git 合并代码

    分支 dev 及衍生分支 dev-ctj 一.rebase 1.git checkout dev-ctj 2.git rebase -i head~num[num 是本分支的提交数,多个提交数先合并为 ...

  7. 如何学习python,个人的一些简单见解

    什么是重要的东西 思考学习是一个什么样的过程 我们每个人都学习过数学,肯定都知道数学的学习过程是什么,我们刚开始学习数学的时候会学习一些简单的公式和概念,比如加减乘除,随着学习的深入,我们发现在大学之 ...

  8. Docker笔记(十二):Docker Compose入门

    1. Compose简介 Docker Compose是Docker官方的用于对Docker容器集群实现编排,快速部署分布式应用的开源项目.Docker Compose通过docker-compose ...

  9. 用 GitBook 创建一本书

    用 GitBook 创建一本书 Gitbook 首先是一个软件,它使用 Git 和 Markdown 来编排书本,如果你没有听过 Git 和 Markdown,那么 gitbook 可能不适合你直接入 ...

  10. 消除router-link 的下划线问题

    <div class="small-size"> <router-link to="/About"> <img src=" ...