SOJ 1015

来源:互联网 发布:电气专业软件 编辑:程序博客网 时间:2024/06/03 18:49

1015. Jill's Tour Paths

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

Every year, Jill takes a bicycle tour between two villages. There are different routes she can take between these villages, but she does have an upper limit on the distance that she wants to travel. Given a map of the region indicating the cities and the roads between them (and their distances), Jill would like to have a list of the various routes between the selected cities that will meet her distance requirements. Your task is to write a program that will produce a list of these routes, in increasing order of distance.

 We make the following assumptions.  

  • At most one road connects any pair of villages, and this road is two-way and has a non-zero positive distance.  
  • There are no roads that lead directly from a village back to the same village.  
  • Jill is only concerned about a one-way trip. That is, she is not concerned about returning to the village from which she starts her tour.  
  • Jill will not visit any village more than once during the tour.

The farthest Jill will ever travel is 9999 units

Input

The input will contain several possible cases, each including a route map, identification of the start and destination villages, and the maximum distance Jill is willing to travel.  

Each case appears in the input as a set of integers separated by blanks and/or ends of lines. The order and interpretation of these integers in each case is as follows:  

  • NV – the number of villages in the route map. This number will be no larger than 20.  
  • NR – the number of roads that appear in the route map. Each road connects a distinct pair of villages.  
  • NR triples, one for each road, containing C1C2, and DIST – C1 and C2 identify two villages connected by a road, and DIST gives the distance between these villages on that road.  
  • SV, DV – the numbers associated with the start and destination villages; the villages are numbered 1 to NV.  
  • MAXDIST – the maximum distance Jill is willing to travel (one way).  

The data for the last case will be followed by a single integer with the value –1.

Output

For each case, display the case number (1, 2, …) on the first line of output. Then, each on a separate additional line, list the routes that Jill might take preceded by the length of the route. Order the routes first by length, from shortest to longest. Within routes having the same length, order them in increasing lexicographic order. The sample input and output provide suitable examples, and the formatting shown there should be followed closely (each village number should be separated by a single space). Separate the output for consecutive cases by a single blank line. If there is no route, print out " NO ACCEPTABLE TOURS"(notice there is one space at the front).

Sample Input

4 51 2 21 3 31 4 12 3 23 4 41 344 51 2 21 3 31 4 12 3 23 4 41 4105 71 2 21 4 52 3 12 4 22 5 33 4 33 5 21 385 71 2 21 4 52 3 12 4 22 5 33 4 33 5 21 31-1

Sample Output

Case 1: 3: 1 3 4: 1 2 3Case 2: 1: 1 4 7: 1 3 4 8: 1 2 3 4Case 3: 3: 1 2 3 7: 1 2 4 3 7: 1 2 5 3 8: 1 4 2 3 8: 1 4 3Case 4: NO ACCEPTABLE TOURS


  有权无向图给出起点和终点寻找可行路径的问题,只要利用深搜寻找出所有的可行路径,深搜时的剪枝条件就是当前路径总长度要不大于限定最大长度,然后将所有可行路径存储在容器中,最后按要求进行排序然后输出即可。要注意最后的输出格式不要弄错。具体步骤写在代码注释上。

#include<iostream>#include<algorithm>#include<vector>#include<iterator>using namespace std;#define Max_n 21struct answer{//一条答案路径 int ans;//数据成员包含这条路径的长度 vector<int> path;//存储这条路径经过的节点(不包含起始点) answer(){ans=0;}}; int city[Max_n];//记录城市是否被访问过,被访问过记为1,每个城市最多被访问一次 int flag;//用来标记是否找到了一条符合条件的路径 int farthest;//用来存储最大限制距离 int weight[Max_n][Max_n];//权重矩阵,保存不同城市间的距离,不相通的城市间的值为0 int numOfCity,numOfPath;//存储城市数量和路的总数量 int startCity,endCity;//存储起始城市和终点城市 answer Ans;//answer类型对象,用来保存当前的寻找情况 bool havePath;//标记是否能找到可行路径 vector<answer> allAnswer;//对于某一例,所有的可行路径均存在这个容器中 bool com(answer A,answer B)//自定义sort的比较函数,先比较路径的长度,相同则再比较路径上节点的字典序 {if(A.ans!=B.ans) return A.ans<B.ans;else return A.path<B.path;}void resetCity()//每次深搜前将所有城市重新全部置为未访问 {for(int i=0;i<Max_n;++i){city[i]=0;}}void makeG()//建图 {int city1,city2,distance;for(int i=1;i<Max_n;++i)//每次建图前要先将矩阵清零 {for(int j=1;j<Max_n;++j)    weight[i][j]=0;    }for(int i=0;i<numOfPath;++i){cin>>city1>>city2>>distance;weight[city1][city2]=weight[city2][city1]=distance;//注意题目是无向图,所以weight[i][j]和weight[j][i]均赋值 }}void DFS(int start,int end)//深搜寻找可行路径,剪枝条件就是当前路径总长度是否大于限制长度 {city[start]=1;if(start==end)//起始点终点相同即成功找到一条(递归的终止条件) {flag=1;return;}for(int i=1;i<=numOfCity;++i)//依次寻找可行城市 {if(weight[start][i]&&!city[i])//满足两城市连通且city[i]在本次寻找中未被访问过 {if(Ans.ans+weight[start][i]<=farthest)//满足选了i城市路径长度未超过限制则可行 {Ans.ans+=weight[start][i];//更新当前的寻找状态 Ans.path.push_back(i);DFS(i,end);//以i为起点进行递归寻找 if(flag)//找到可行解 {havePath=true;allAnswer.push_back(Ans);//将此可行解存储进容器 }Ans.ans-=weight[start][i];//回溯,恢复历史状态,进行下一种可行解的寻找 Ans.path.pop_back();flag=0;city[i]=0;}}}}int main(){int count=0;//记录case的数量 bool firstTime=true;while(cin>>numOfCity&&numOfCity!=-1&&cin>>numOfPath){makeG();cin>>startCity>>endCity>>farthest;Ans.ans=0;//注意对于每一个case要将相关变量清空恢复初始状态 Ans.path.clear();    resetCity();    havePath=false;flag=0;allAnswer.clear();DFS(startCity,endCity);//深搜 if(!firstTime){cout<<endl;}else{firstTime=false;}cout<<"Case "<<++count<<":"<<endl;if(!havePath)//输出无路径的结果 {cout<<" NO ACCEPTABLE TOURS"<<endl;}else//存在可行路径 {sort(allAnswer.begin(),allAnswer.end(),com);//按题意进行排序再输出     for(vector<answer> ::iterator iter=allAnswer.begin();iter!=allAnswer.end();iter++)    {    cout<<" "<<iter->ans<<": "<<startCity;for(vector<int> ::iterator j=iter->path.begin();j!=iter->path.end();++j){cout<<" "<<*j;}cout<<endl;    }}}}


0 0