zoukankan      html  css  js  c++  java
  • 图的遍历 | 1131地铁图: dfs复杂模拟题

    这题在搞清楚思路绕过坑后,还是可以写的出通过sample data的代码的。但是不能AC,让我很气。

    最后查清原因:还是对dfs本质理解的不够。

    wa代码:

    vis[s]=1;
    dfs(s,e,0);

    殊不知本题有多个查询数据。如果只调用一遍还可以蒙混过关,但是这样的错误必然导致wa

    ac代码:

    vis[s]=1;
    dfs(s,e,0);
    vis[s]=0;

    参考柳诺博客修改的AC代码:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 10000
    #define MAX 0x06FFFFFF
    #define V vector<int>
    
    using namespace std;
    
    vector<int> g[LEN];
    int line[LEN][LEN];
    int vis[LEN];
    vector<int> path;
    vector<int> ans;
    int min_d=MAX;
    int min_ls=MAX;
    
    int N,M,K;
    
    int calc_ls(){
        int cnt=-1,preLine=0;
        for(int i=1;i<path.size();i++){
            if(line[path[i-1]][path[i]]!=preLine) cnt++;
            preLine=line[path[i-1]][path[i]];
        }
        return cnt;
    }
    
    void dfs(int s,int e,int d){
        if(s==e){
            int ls=calc_ls();
            if(d<min_d || (d==min_d && ls<min_ls)){
                min_d=d;
                min_ls=ls;
                ans=path;
            }
            return;
        }
        int i;
        FF(i,g[s].size()){
            int o=g[s][i];
            if(!vis[o]){
                vis[o]=1;
                path.push_back(o);
                dfs(o,e,d+1);
                vis[o]=0;
                path.pop_back();
            }
        }
    
    }
    
    void printLine(){
        int s=ans[0];
        int preL=0;
        int i;
        F(i,1,ans.size()){
            if(line[ans[i-1]][ans[i]]!=preL){
                if(preL) printf("Take Line#%d from %04d to %04d.
    ",preL,s,ans[i-1]);
                s=ans[i-1];
                preL=line[ans[i-1]][ans[i]]; 
            }
        }
        printf("Take Line#%d from %04d to %04d.
    ",preL,s,ans[i-1]);
    }
    
    int main(){
    //    freopen("1131.txt","r",stdin);
        int s,e,i,j;
        I("%d",&N);
        F(i,1,N+1){
            int pre,p=-1;
            I("%d",&M);
            while(M--){
                pre=p;
                I("%d",&p);
                if(pre>=0){
                    g[p].push_back(pre);
                    g[pre].push_back(p);
                    line[p][pre]=i;
                    line[pre][p]=i;
                }
            }
        }
        I("%d",&K);
        while(K--){
            min_d=MAX;
            min_ls=MAX;
            path.clear();
            ans.clear();
            I("%d%d",&s,&e);
            path.push_back(s);
            vis[s]=1;
            dfs(s,e,0);
            vis[s]=0;
            O("%d
    ",min_d);
            printLine();
        }
        return 0;
    }
    View Code

    在自己思路上修改的AC代码:(个人认为比柳诺的好理解)

      1 #include <stdio.h>
      2 #include <memory.h>
      3 #include <math.h>
      4 #include <string>
      5 #include <vector>
      6 #include <set>
      7 #include <stack>
      8 #include <queue>
      9 #include <algorithm>
     10 #include <map>
     11 
     12 
     13 #define I scanf
     14 #define OL puts
     15 #define O printf
     16 #define F(a,b,c) for(a=b;a<c;a++)
     17 #define FF(a,b) for(a=0;a<b;a++)
     18 #define FG(a,b) for(a=b-1;a>=0;a--)
     19 #define LEN 10000
     20 #define MAX 0x06FFFFFF
     21 #define V vector<int>
     22 
     23 using namespace std;
     24 
     25 vector<int> g[LEN];
     26 int line[LEN][LEN];
     27 int vis[LEN];
     28 vector<int> path;
     29 vector<int> ans;
     30 int min_d=MAX;
     31 int min_ls=MAX;
     32 
     33 int N,M,K;
     34 
     35 void dfs(int s,int e,int d,int l,int ls){
     36     if(s==e){
     37         if(d<min_d || (d==min_d && ls<min_ls)){
     38             min_d=d;
     39             min_ls=ls;
     40             ans=path;
     41         }
     42         return;
     43     }
     44     int i;
     45     FF(i,g[s].size()){
     46         int o=g[s][i];
     47         if(!vis[o]){
     48             vis[o]=1;
     49             path.push_back(o);
     50             int nl=line[s][o];
     51             int nls=ls;
     52             if(l==0){    //初始结点 
     53                 nls=1;
     54             }else{
     55                 if(nl!=l) nls++;
     56             }
     57             dfs(o,e,d+1,nl,nls);
     58             vis[o]=0;
     59             path.pop_back();
     60         }
     61     }
     62 
     63 }
     64 
     65 void printLine(){
     66     int s=ans[0];
     67     int preL=line[s][ans[1]];
     68     int i;
     69     F(i,1,ans.size()){
     70         if(line[ans[i-1]][ans[i]]!=preL){
     71             printf("Take Line#%d from %04d to %04d.
    ",preL,s,ans[i-1]);
     72             s=ans[i-1];
     73             preL=line[ans[i-1]][ans[i]]; 
     74         }
     75     }
     76     printf("Take Line#%d from %04d to %04d.
    ",preL,s,ans[i-1]);
     77 }
     78 
     79 int main(){
     80 //    freopen("1131.txt","r",stdin);
     81     int s,e,i,j;
     82     I("%d",&N);
     83     F(i,1,N+1){
     84         int pre,p=-1;
     85         I("%d",&M);
     86         while(M--){
     87             pre=p;
     88             I("%d",&p);
     89             if(pre>=0){
     90                 g[p].push_back(pre);
     91                 g[pre].push_back(p);
     92                 line[p][pre]=i;
     93                 line[pre][p]=i;
     94             }
     95         }
     96     }
     97     I("%d",&K);
     98     while(K--){
     99         min_d=MAX;
    100         min_ls=MAX;
    101         path.clear();
    102         ans.clear();
    103         I("%d%d",&s,&e);
    104         vis[s]=1;
    105         dfs(s,e,0,0,0);
    106         vis[s]=0;
    107         O("%d
    ",ans.size());
    108         ans.insert(ans.begin(),s);
    109         printLine();
    110     }
    111     return 0;
    112 }

    注意点:

    ① 38 39 行,对维护的最小距离和最小换乘次数进行更新,不要写错(我开始写成了d=min_d ,查了很久的错,蠢哭……)

    ② 99 100 行,将最小距离和最小换乘次数重新初始化为INF。

    ③ 106 行,牢记 dfs 结构

  • 相关阅读:
    【Python3】调用webserver接口
    【Robot Framework】字符串判断,if语句多执行条件,多执行语句
    【Robot Framework】BuiltIn库
    jenkins运行报错的两个坑
    【Python3】jsonpath-rw处理Json对象
    使用Grunt自动化任务
    用nodesjs+grunt+bower+angularjs搭建项目
    浅谈AngularJS中的$parse和$eval
    AngularJS Controller之间的通信
    AngularJS动态绑定html
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8543161.html
Copyright © 2011-2022 走看看