1018. Public Bike Management (30) @ PAT (Advanced Level) Practise
2013-08-21 14:23
435 查看
对Dijkstra算法的复习
求解从s点到t点的最短路径#include<iostream> #include<vector> using namespace std; #define INF 0x6FFFFFFF struct Edge { int v,dist; Edge(int _v,int _dist):v(_v),dist(_dist){} }; struct Node { int dist; bool visited; vector<int> pre; }; vector<Node> city; vector<vector<Edge>> G; int n;//vertexs int m;//edges void Dijkstra(int s,int t) { //init city.clear(); city.resize(n+1); for(int i=0;i<=n;i++) { city[i].visited=false; city[i].dist=INF; } city[s].dist=0; while(true) { //find min int index=-1; int mindist=INF; for(int i=0;i<=n;i++) { if(city[i].dist<mindist && !city[i].visited) { index=i; mindist=city[i].dist; } } if(index==-1) return ; city[index].visited=true; //scan the neighborhood for(int i=0;i<G[index].size();i++) { int v=G[index][i].v; if(!city[v].visited) { if(city[v].dist>(city[index].dist+G[index][i].dist)) { city[v].pre.clear(); city[v].pre.push_back(index); city[v].dist=city[index].dist+G[index][i].dist; } else if(city[v].dist==(city[index].dist+G[index][i].dist)) { city[v].pre.push_back(index); } } } } return ; } int main() { cin>>n>>m; int a,b,c; G.clear(); G.resize(n+1); for(int i=0;i<m;i++) { cin>>a>>b>>c; G[a].push_back(Edge(b,c)); G[b].push_back(Edge(a,c)); } while(true) { int s,t; cin>>s>>t; if(s==-1 || t==-1) break; Dijkstra(s,t); cout<<"smallest dist:"<<city[t].dist<<endl; for(int i=0;i<city.size();i++) { cout<<"vertex["<<i<<"]:"<<city[i].dist<<" "; for(int j=0;j<city[i].pre.size();j++) { cout<<city[i].pre[j]<<" "; } cout<<endl; } } return 0; }
2个测试用的图:
6 9 0 1 7 0 2 9 0 5 14 1 2 10 1 3 15 2 3 11 2 5 2 3 4 6 4 5 9 ============== 4 5 0 1 1 0 2 1 0 3 3 1 3 1 2 3 1 ============== 8 9 0 1 1 0 2 1 1 3 1 1 4 1 2 5 1 2 6 1 3 7 1 4 7 1 5 6 1
复习一下DFS
ps.关于DFS遍历最短路径,在下面一小节中#include<iostream> #include<vector> using namespace std; #define INF 0x6FFFFFFF struct Edge { int v,dist; Edge(int _v,int _dist):v(_v),dist(_dist){} }; struct Node { int dist; bool visited; vector<int> pre; }; vector<Node> city; vector<vector<Edge>> G; vector<int> DFSPath; int n;//vertexs int m;//edges void Dijkstra(int s,int t) { //init city.clear(); city.resize(n+1); for(int i=0;i<=n;i++) { city[i].visited=false; city[i].dist=INF; } city[s].dist=0; while(true) { //find min int index=-1; int mindist=INF; for(int i=0;i<=n;i++) { if(city[i].dist<mindist && !city[i].visited) { index=i; mindist=city[i].dist; } } if(index==-1) return ; city[index].visited=true; //scan the neighborhood for(int i=0;i<G[index].size();i++) { int v=G[index][i].v; if(!city[v].visited) { if(city[v].dist>(city[index].dist+G[index][i].dist)) { city[v].pre.clear(); city[v].pre.push_back(index); city[v].dist=city[index].dist+G[index][i].dist; } else if(city[v].dist==(city[index].dist+G[index][i].dist)) { city[v].pre.push_back(index); } } } } return ; } void DFS(int s,int t) { city[s].visited=true; DFSPath.push_back(s); for(int i=0;i<G[s].size();i++) { int v=G[s][i].v; if(!city[v].visited) { DFS(v,t); } } return; } int main() { cin>>n>>m; int a,b,c; G.clear(); G.resize(n+1); for(int i=0;i<m;i++) { cin>>a>>b>>c; G[a].push_back(Edge(b,c)); G[b].push_back(Edge(a,c)); } while(true) { int s,t; cin>>s>>t; if(s==-1 || t==-1) break; //Dijkstra Dijkstra(s,t); cout<<"smallest dist:"<<city[t].dist<<endl; for(int i=0;i<city.size();i++) { cout<<"vertex["<<i<<"]:"<<city[i].dist<<" "; for(int j=0;j<city[i].pre.size();j++) { cout<<city[i].pre[j]<<" "; } cout<<endl; } //DFS //init for(int i=0;i<city.size();i++) city[i].visited=false; DFS(s,t); //display the path for(int j=0;j<DFSPath.size();j++) cout<<DFSPath[j]<<" " ; cout<<endl; } return 0; }
A1018的解
整体思路:首先用Dijkstra算法找到所有最短路径,并在每个节点上记录最短路径时的所有前缀。然后从目标点到源(t->s)按每个结点记录的前缀向量表深度优先遍历(DFS,findBestPath函数)出所有最短的路径。对每条最短路径计算需要带出的车数(TakeTo)和带回的车数(TakeBack),与最佳路径的这两个值比较即可。关于DFS遍历最短路径
DFS(s,t) push(s) foreach v in neighborhood of s if v==t push(v) continue else DFS(v,t) pop() end
A1018代码:
#include<iostream> #include<vector> using namespace std; #define INF 0x6FFFFFFF struct Edge { int v,dist; Edge(int _v,int _dist):v(_v),dist(_dist){} }; struct Node { int dist; bool visited; int c; vector<int> pre; }; vector<Node> city; vector<vector<Edge>> G; vector<int>bPath;//best path vector<int>cPath;//current path int bTakeTo=0,bTakeBack=0,cTakeTo=0,cTakeBack=0; vector<int>::reverse_iterator rit; //vector<int> DFSPath; int cmax;//max capacity of each station int n;//vertexs int sp;//target station int m;//edges int hfull; void Dijkstra(int s,int t) { for(int i=0;i<=n;i++) { city[i].visited=false; city[i].dist=INF; } city[s].dist=0; while(true) { //find min int index=-1; int mindist=INF; for(int i=0;i<=n;i++) { if(city[i].dist<mindist && !city[i].visited) { index=i; mindist=city[i].dist; } } if(index==-1) return ; city[index].visited=true; //scan the neighborhood for(int i=0;i<G[index].size();i++) { int v=G[index][i].v; if(!city[v].visited) { if(city[v].dist>(city[index].dist+G[index][i].dist)) { city[v].pre.clear(); city[v].pre.push_back(index); city[v].dist=city[index].dist+G[index][i].dist; } else if(city[v].dist==(city[index].dist+G[index][i].dist)) { city[v].pre.push_back(index); } } } } return ; } void findBestPath(int s,int t) { cPath.push_back(t); for(int i=0;i<city[t].pre.size();i++) { int v=city[t].pre[i]; if(v!=s) { findBestPath(s,v); } else { if(bPath.empty()) { //update best path info bPath.assign(cPath.begin(),cPath.end()); for(rit=bPath.rbegin();rit!=bPath.rend();rit++) { if(city[*rit].c<hfull) { if(bTakeBack>hfull-city[*rit].c) { bTakeBack-=hfull-city[*rit].c; } else if(bTakeBack>0) { bTakeTo+=hfull-city[*rit].c-bTakeBack; bTakeBack=0; } else { bTakeTo+=hfull-city[*rit].c; } } else if(city[*rit].c>hfull) { bTakeBack+=city[*rit].c-hfull; } } } else { //calculate cTakeTo & cTakeBack for(rit=cPath.rbegin();rit!=cPath.rend();rit++) { if(city[*rit].c<hfull) { if(cTakeBack>hfull-city[*rit].c) cTakeBack-=hfull-city[*rit].c; else if(cTakeBack>0) { cTakeTo+=hfull-city[*rit].c-cTakeBack; cTakeBack=0; } else cTakeTo+=hfull-city[*rit].c; } else if(city[*rit].c>hfull) { cTakeBack+=city[*rit].c-hfull; } } //compare cPath & bPath if(bTakeTo>cTakeTo || (bTakeTo==cTakeTo && bTakeBack>cTakeBack)) { bTakeTo=cTakeTo; bTakeBack=cTakeBack; bPath.assign(cPath.begin(),cPath.end()); } } //clear current path info continue; cTakeTo=0; cTakeBack=0; } } cPath.pop_back(); cTakeTo=0; cTakeBack=0; return ; } int main() { cin>>cmax>>n>>sp>>m; hfull=cmax/2; //init city.clear(); city.resize(n+1); for(int i=1;i<=n;i++) cin>>city[i].c; int a,b,c; G.clear(); G.resize(n+1); for(int i=0;i<m;i++) { cin>>a>>b>>c; G[a].push_back(Edge(b,c)); G[b].push_back(Edge(a,c)); } int s=0,t=sp; //Dijkstra Dijkstra(s,t); cPath.clear(); bPath.clear(); //DFS findBestPath(s,t); cout<<bTakeTo<<" "; cout<<s<<"->"; for(int i=bPath.size()-1;i>0;i--) cout<<bPath[i]<<"->"; cout<<t<<" "; cout<<bTakeBack; return 0; }
相关文章推荐
- PAT (Advanced Level) Practise 1026 Table Tennis (30)
- 1022. Digital Library (30) @ PAT (Advanced Level) Practise
- 1057. Stack (30)【栈+树状数组】——PAT (Advanced Level) Practise
- 1091. Acute Stroke (30)【搜索】——PAT (Advanced Level) Practise
- PAT (Advanced Level) Practise 1064 Complete Binary Search Tree (30)
- PAT (Advanced Level) Practise 1057 Stack (30)
- PAT (Advanced Level) Practise 1018 Public Bike Management (30)
- PAT (Advanced Level) Practise 1018. Public Bike Management (30)
- PAT (Advanced Level) Practise 1022. Digital Library (30)
- 1026. Table Tennis (30)【排序+模拟+逻辑复杂】——PAT (Advanced Level) Practise
- PAT (Advanced Level) Practise 1057 Stack (30)
- PAT (Advanced Level) Practise 1095 Cars on Campus (30)
- PAT (Advanced Level) Practise 1115 Counting Nodes in a BST (30)
- PAT (Advanced Level) Practise 1107 Social Clusters (30)
- PAT (Advanced Level) Practise 1004. Counting Leaves (30)
- PAT (Advanced Level) Practise 1018. Public Bike Management (30)
- 1068. Find More Coins (30)【背包】——PAT (Advanced Level) Practise
- PAT (Advanced Level) Practise 1107 Social Clusters (30)
- PAT (Advanced Level) Practise 1099 Build A Binary Search Tree (30)
- 1076. Forwards on Weibo (30)【树+搜索】——PAT (Advanced Level) Practise