poj2197||zoj2406 Jill's Tour Paths(回溯+优先队列)

                                                                                                                                            Jill's Tour Paths
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 1361 Accepted: 407

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 C1, C2, 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).
If there is no route, print out " NO ACCEPTABLE TOURS"
Separate the output for consecutive cases by a single blank line.

Sample Input

4 5
1 2 2
1 3 3
1 4 1
2 3 2
3 4 4
1 3
4

4 5
1 2 2
1 3 3
1 4 1
2 3 2
3 4 4
1 4
10

5 7
1 2 2
1 4 5
2 3 1
2 4 2
2 5 3
3 4 3
3 5 2
1 3
8

-1

Sample Output

Case 1:
 3: 1 3 
 4: 1 2 3 

Case 2:
 1: 1 4 
 7: 1 3 4 
 8: 1 2 3 4 

Case 3:
 3: 1 2 3 
 7: 1 2 4 3 
 7: 1 2 5 3 
 8: 1 4 2 3 
 8: 1 4 3 
题目大意:给定一张无向图,起点sv,终点dv,和一个距离上限MAXDIST,求从起点到终点所有距离和不超过MAXDIST的路线,并将其按照最小上升字典序输出.
本题思路清楚,从整个解答树中找到符合要求的路线.由于数据量不是很大(n<=20),故,这是典型的---回溯法求解的题目,本题的关键就是保存并输出结果。
我的方法,我采用的是----优先队列(有些人用双重vector.)
另外需要掌握的是这个小知识点,  vector<int>a,b;   a<b表示:如果a的字典序小于b则返回true,否则返回false;
再次吐槽一下,题目中那个特例输出" NO ACCEPTABLE TOURS" 前面居然有个空格,我艹。。一直wa啊
/*
    @author : liuwen
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <climits> //INT_MAX INT_MIN LONG_LONG_MAX LONG_LONG_MIN
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxe=5000+5;
struct HeapNode{  //优先队列
    int d;
    vector<int>ans;
    bool operator < (const HeapNode& r) const{
        if(r.d!=d) return r.d<d;
        else  return r.ans<ans;  //如果距离相同,按照字典序
    }
    HeapNode(int d,vector<int>ans):d(d),ans(ans){}; //构造函数
};
struct NodeEdge{
    int to,w,next;
}edges[maxe];
int head[25],vis[25],nEdges,n,m,st,ed,limit;
bool hasPath=false;
vector<int>p;
priority_queue<HeapNode>path;
void addEdges(int u,int v,int w)
{
    nEdges++;
    edges[nEdges].to=v;
    edges[nEdges].w=w;
    edges[nEdges].next=head[u];
    head[u]=nEdges;
}
void dfs(int u,int cnt,int sum)
{
    vis[u]=1;
    p.push_back(u);
    if(sum>limit)   return;
    if(u==ed){
        path.push(HeapNode(sum,p));
        hasPath=true;
        return;
    }
    for(int k=head[u];k!=-1;k=edges[k].next){
        int v=edges[k].to;
        if(!vis[v]){
            dfs(v,cnt+1,sum+edges[k].w);
            vis[v]=0;        //回溯
            p.pop_back(); //回溯
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int cas=0;
    while(scanf("%d",&n)==1){
        if(n==-1)break;
        if(cas>0)   printf("\n");
        scanf("%d",&m);
        memset(head,-1,sizeof(head));
        memset(edges,0,sizeof(edges));
        memset(vis,0,sizeof(vis));
        p.clear();
        nEdges=0;
        hasPath=false;
        for(int i=1;i<=m;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            addEdges(u,v,w);
            addEdges(v,u,w);
        }
        scanf("%d%d%d",&st,&ed,&limit);
        dfs(st,0,0);
        printf("Case %d:\n",++cas);
        if(!hasPath) printf(" NO ACCEPTABLE TOURS\n");
        else{
            while(!path.empty()){
                HeapNode t=path.top();
                path.pop();
                printf(" %d:",t.d);
                for(vector<int>::size_type i=0;i<t.ans.size();i++){
                    printf(" %d",t.ans[i]);
                }
                printf("\n");
            }
        }
    }
    return 0;
}
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值