• PAT甲级1018留坑——第一个测试点未过(Dijikstar+Dfs)


    题目分析:

    主要是先进行狄杰斯特拉求出0点到每个点的最短路后用dfs求出所有的路径,将路径方案加入vector排序选择need最小和rest最小的方案,但是第一个测试却过不去,欢迎指正!!感谢!!

    值得注意的是对于一条路径上的所有点进行调整的时候只能一步一步下来,后来多出的车不能用于调整前面走过的点的数量(很重要)

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<vector>
      4 #include<string.h>
      5 using namespace std;
      6 
      7 const int M = 0x3f3f3f3f;
      8 int c, n, sp, m;
      9 int mat[505][505];
     10 int vis[505];                        //第一次用于作为求dist记录该点是否到达 第二次用于深搜回溯记录是否走过该点
     11 int num[505];
     12 int dist[505];
     13 int les_dist = M;
     14 struct Node{
     15     int need;
     16     int rest;
     17     int distance;
     18     vector<int> road;
     19 };
     20 
     21 vector<Node> r;                        //用于存放多个最短路情况下的行走方案,一个数据结构存放一个方案的信息
     22 
     23 int minn(){
     24     int k = -1;
     25     int Min = M;
     26     int i;
     27     for(i = 1; i <= n; i++){
     28         if(vis[i] == 0 && dist[i] < Min){
     29             Min = dist[i];
     30             k = i;
     31         }
     32     }
     33     return k;
     34 }
     35 
     36 void run1(){
     37     int i;
     38     for(i = 0; i <= n; i++){        //将从0点开始到其他点的距离设为到该点的最小值
     39         dist[i] = mat[0][i];
     40     }    
     41     for(i = 1; i <= n; i++){        //包含0点则有n+1个点 需要进行n次查询
     42         int k = minn();                
     43         if(k == -1) break;            //查询次数未用完但k==-1则代表图不连通 退出循环
     44         vis[k] = 1;
     45         int j;
     46         for(j = 1; j <= n; j++){
     47             if(vis[j] == 0 && dist[k] + mat[k][j] < dist[j]){
     48                 dist[j] = dist[k] + mat[k][j];
     49             }
     50         }
     51     }
     52     les_dist = dist[sp];            //全局变量les_dist存放到达终点的最短路径
     53 }
     54 
     55 void dfs(Node s, int x){
     56     //对于当前点x来说 需要判断此时存放路径数据的长度加到达x的长度和最短路径长度的关系
     57     int pre = s.road.back();    //前一个点
     58     if(s.distance + mat[pre][x] <= les_dist){        
     59         s.distance += mat[pre][x];
     60         if(num[x] < c/2){        //需要对该点的自行车的数量进行调整
     61             if(s.rest >= c/2 - num[x]){
     62                 s.rest -= (c/2 - num[x]);
     63             }else{                //剩余的不够 
     64                 s.need += c/2 - num[x] - s.rest;    //需要的总数减去有的总数则为需要从0点发出的数量
     65                 s.rest = 0; 
     66             }
     67         }else if(num[x] > c/2){
     68             s.rest += num[x] - c/2;    //对多余的车都放入rest中 
     69         }
     70         s.road.push_back(x);    //将x加入已经走过的点的队列 
     71         //当点加完之后判断是否到了终点
     72         if(x == sp){
     73             r.push_back(s);        //将s这个路径选择方案加入vector r 
     74         } 
     75     }
     76     if(sp == x) return;
     77     vis[x] = 1;
     78     int i;
     79     for(i = 1; i <= n; i++){
     80         if(vis[i] == 0 && mat[x][i] != M){
     81             dfs(s, i);
     82             vis[i] = 0;
     83         }        
     84     }
     85 }
     86 
     87 bool cmp(Node a, Node b){
     88     if(a.need != b.need) a.need < b.need;
     89     else{
     90         return a.rest < b.rest;
     91     }
     92 }
     93 
     94 void run2(){
     95     memset(vis, 0, sizeof(vis));    //此次的vis需要重新清零
     96     Node s;
     97     s.need = 0;
     98     s.rest = 0;
     99     s.distance = 0;
    100     s.road.push_back(0);            //将0点作为起始点 
    101     dfs(s, 0);                        //从0点开始 其中s为当前存放路径数据的数据结构
    102     sort(r.begin(), r.end(), cmp); 
    103     Node ans = r.front();
    104     if(sp != 0){
    105         printf("%d ", ans.need);
    106         int i;
    107         for(i = 0; i < ans.road.size(); i++){
    108             if(i != 0) printf("->");
    109             printf("%d", ans.road[i]);
    110         }
    111         printf(" %d
    ", ans.rest);
    112     }else{
    113         printf("0 0 0
    ");
    114     }
    115 }
    116 
    117 int main(){
    118     scanf("%d%d%d%d", &c, &n, &sp, &m);
    119     memset(mat, M, sizeof(mat));
    120     memset(vis, 0, sizeof(vis));
    121     int i;
    122     for(i = 1; i <= n; i++){        //输入没个点的自行车数量
    123         scanf("%d", &num[i]);
    124     }
    125     for(i = 0; i < m; i++){
    126         int x, y, z;
    127         scanf("%d%d%d", &x, &y, &z);
    128         mat[x][y] = z;
    129         mat[y][x] = z;
    130     }    
    131     run1();                            //这部分完成了从起点到sp点的最短路径的计算
    132     run2();                            //通过bfs查询出通路然后加入vector
    133     return 0;
    134 }
  • 相关阅读:
    http 协议相关问题
    网卡中断及多队列
    Visual Studio Code 配置C/C++环境
    C++通用框架和库
    命令行的艺术
    NetScaler Logs Collection Guide
    C++性能榨汁机之无锁编程
    Codeforces 839E Mother of Dragons【__builtin_popcount()的使用】
    C/C++中__builtin_popcount()的使用及原理
    Codeforces 839D Winter is here【数学:容斥原理】
  • 原文地址:https://www.cnblogs.com/findview/p/11759658.html
Copyright © 2020-2023  润新知