1131 Subway Map

link

 

 

 

 

思路:

不可以bfs求最短路!因为到达中间点的最短路可能不唯一,无法取舍,而且中间点的选择会影响到后面点,必须全部考虑中间点的情况。

只能dfs了。

 

#include <iostream>
#include <cstring>
#include <vector>
#include <unordered_map>
#include <climits>
# define LL long long
using namespace std;

vector<vector<int>> adj(10000);
unordered_map<int,unordered_map<int,int>> line;
vector<int> finalpath;
int transfers;
int mincnt;
int visited[10000];

int countTransfers(vector<int>& path){
    int preline=0;
    int res=0;
    for(int i=0;i<path.size()-1;i++){
        int u=path[i];
        int v=path[i+1];
        int curline=line[u][v];
        if(preline==0){
            preline=curline;
            continue;
        }
        if(curline!=preline){
            preline=curline;
            res++;
        }
    }
    return res;
}

void dfs(int u, int v, int cnt, vector<int>& path){
    if(visited[u]==1) return;
    if(cnt>mincnt) return;
    if(u==v){
        path.push_back(v);
        if(cnt<mincnt){
            mincnt=cnt;
            finalpath=path;
            transfers=countTransfers(path);
        }else if(cnt==mincnt){
            int tmp=countTransfers(path);
            if(tmp<transfers){
                transfers=tmp;
                finalpath=path;
            }
        }
        path.pop_back();
        return;
    }

    visited[u]=1;
    path.push_back(u);
    for(int next:adj[u]){
        dfs(next,v,cnt+1,path);
    }
    visited[u]=0;
    path.pop_back();
}

int main(){
    int N;
    cin>>N;
    for(int i=1;i<=N;i++){
        int cnt;
        cin>>cnt;
        int pre;
        cin>>pre;
        for(int j=1;j<cnt;j++){
            int cur;
            cin>>cur;
            adj[pre].push_back(cur);
            adj[cur].push_back(pre);
            line[cur][pre]=i;
            line[pre][cur]=i;
            pre=cur;
        }
    }

    int K;
    cin>>K;
    for(int i=0;i<K;i++){
        memset(visited,0,sizeof(visited));
        int u,v;
        cin>>u>>v;
        vector<int> path;
        mincnt=INT_MAX;
        dfs(u,v,0,path);
        printf("%d\n", finalpath.size()-1);
        int preline=0;
        int start=u;
        for(int j=0;j<finalpath.size()-1;j++){
            int a=finalpath[j];
            int b=finalpath[j+1];
            int curline=line[a][b];
            if(preline==0){
                preline=curline;
            }else{
                if(preline!=curline){
                    printf("Take Line#%d from %04d to %04d.\n", preline,start,a);
                    start=a;
                    preline=curline;
                }
            }
            if(b==v){
                printf("Take Line#%d from %04d to %04d.\n", curline,start,v);
            }
        }
    }
    return 0;
}

 

用一个结构体存station id 以及 线路 id:

#include <iostream>
#include <cstring>
#include <vector>
#include <unordered_map>
#include <climits>
#include <queue>
# define LL long long
using namespace std;


vector<int> finalpath;
vector<int> finallinepath;
int transfers;
int mincnt;
int visited[10000];

struct Sta{
    int id;
    int lineid;
    Sta(int i, int l):id(i),lineid(l) {}
};
vector<vector<Sta>> adj(10000);

int countTransfers(vector<int>& linepath){
    int preline=0;
    int res=0;
    for(int i=0;i<linepath.size();i++){
        if(preline==0){
            preline=linepath[i];
            continue;
        }
        if(linepath[i]!=preline){
            preline=linepath[i];
            res++;
        }
    }
    return res;
}



void dfs(int u, int v, int cnt, vector<int>& path, vector<int>& linepath){
    if(visited[u]==1) return;
    if(cnt>mincnt) return;
    if(u==v){
        path.push_back(v);
        if(cnt<mincnt){
            mincnt=cnt;
            finalpath=path;
            finallinepath=linepath;
            transfers=countTransfers(linepath);
        }else if(cnt==mincnt){
            int tmp=countTransfers(linepath);
            if(tmp<transfers){
                transfers=tmp;
                finalpath=path;
                finallinepath=linepath;
            }
        }
        path.pop_back();
        return;
    }

    visited[u]=1;
    path.push_back(u);
    for(auto next:adj[u]){
        linepath.push_back(next.lineid);
        dfs(next.id,v,cnt+1,path,linepath);
        linepath.pop_back();
    }
    visited[u]=0;
    path.pop_back();
}

int main(){
    int N;
    cin>>N;
    for(int i=1;i<=N;i++){
        int cnt;
        cin>>cnt;
        int pre;
        cin>>pre;
        for(int j=1;j<cnt;j++){
            int cur;
            cin>>cur;
            adj[pre].push_back(Sta(cur,i));
            adj[cur].push_back(Sta(pre,i));
            pre=cur;
        }
    }

    int K;
    cin>>K;
    for(int i=0;i<K;i++){
        memset(visited,0,sizeof(visited));
        int u,v;
        cin>>u>>v;
        vector<int> path;
        vector<int> linepath;
        mincnt=INT_MAX;
        dfs(u,v,0,path, linepath);
        printf("%d\n", finalpath.size()-1);
        int preline=0;
        int start=u;
        for(int j=0;j<finalpath.size()-1;j++){
            int a=finalpath[j];
            int b=finalpath[j+1];
            int curline=finallinepath[j];
            if(preline==0){
                preline=curline;
            }else{
                if(preline!=curline){
                    printf("Take Line#%d from %04d to %04d.\n", preline,start,a);
                    start=a;
                    preline=curline;
                }
            }
            if(b==v){
                printf("Take Line#%d from %04d to %04d.\n", curline,start,v);
            }
        }
    }
    return 0;
}

 

posted @ 2020-03-16 18:39  feibilun  阅读(129)  评论(0)    收藏  举报