思路:
不可以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 ", 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. ", preline,start,a); start=a; preline=curline; } } if(b==v){ printf("Take Line#%d from %04d to %04d. ", 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 ", 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. ", preline,start,a); start=a; preline=curline; } } if(b==v){ printf("Take Line#%d from %04d to %04d. ", curline,start,v); } } } return 0; }