poj 1724 ROADS (dfs结构体解法)

Description

N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll that needs to be paid for the road (expressed in the number of coins). 
Bob and Alice used to live in the city 1. After noticing that Alice was cheating in the card game they liked to play, Bob broke up with her and decided to move away - to the city N. He wants to get there as quickly as possible, but he is short on cash. 

We want to help Bob to find the shortest path from the city 1 to the city N that he can afford with the amount of money he has. 

Input

The first line of the input contains the integer K, 0 <= K <= 10000, maximum number of coins that Bob can spend on his way. 
The second line contains the integer N, 2 <= N <= 100, the total number of cities. 

The third line contains the integer R, 1 <= R <= 10000, the total number of roads. 

Each of the following R lines describes one road by specifying integers S, D, L and T separated by single blank characters : 

  • S is the source city, 1 <= S <= N 
  • D is the destination city, 1 <= D <= N 
  • L is the road length, 1 <= L <= 100 
  • T is the toll (expressed in the number of coins), 0 <= T <=100


Notice that different roads may have the same source and destination cities.

Output

The first and the only line of the output should contain the total length of the shortest path from the city 1 to the city N whose total toll is less than or equal K coins. 
If such path does not exist, only number -1 should be written to the output. 

Sample Input

5
6
7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2

Sample Output

11

题目大意:

有一个同学有k元,他想从第一条路到达第n条路问走的长度最小的方案中的花费是多少。

分析:

这个题目让我自己做我是想不到dfs的,我可能会用结构体排序。后来看了pdf才知道可以用dfs,且剪枝的时候我觉得其中一行代码不写影响不大,结果提交超时,深刻的体会到了dfs的重复搜索。代码中有一个技巧就是将结构体压缩在数组中vector<vector<road> >citymap(120); 将每一条路的起始点作为节点来开始搜索,妙实在是妙。

附上vector的用法:

vector容器是一个模板类,可以存放任何类型的对象(但必须是同一类对象)。vector对象可以在运行时高效地添加元素,并且vector中元素是连续存储的。

二  。Vector对象最重要的几种操作
1. v.push_back(t) 在数组的最后添加一个值为t的数据
2. v.size() 当前使用数据的大小
3. v.empty() 判断vector是否为空
4. v[n] 返回v中位置为n的元素
5. v1=v2 把v1的元素替换为v2元素的副本
6. v1==v2 判断v1与v2是否相等
7. !=、<、<=、>、>= 保持这些操作符惯有含义

具体用法请看代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include<vector>
#include<string>

using namespace std;
int k,n,r,totallen=0,totalcast=0;
struct road{
        int d,l,t;
};
int minlen=1 << 30;
int minl[110][10110];
int visit[110];
vector<vector<road> >citymap(120);//注意这里的两个> >中间一定要空格

void dfs(int s)
{
        if(s==n)
        {
                minlen=min(minlen,totallen);
                return ;
        }
        int i;
        for(i=0;i<citymap[s].size();i++)//类似于二维数组与string用法的结合
        {
                int d=citymap[s][i].d;
                if(!visit[d])
                {
                        int cost=totalcast+citymap[s][i].t;
                        if(cost>k)
                                continue;
                        if(totallen + citymap[s][i].l>=minlen||totallen + citymap[s][i].l>=minl[d][cost])//这个地方单纯的判断>=minlen无法ac
                                continue;
                        totallen+=citymap[s][i].l;
                        totalcast+=citymap[s][i].t;
                        minl[d][cost]=totallen;
                        visit[d]=1;
                        dfs(d);
                        visit[d]=0;
                        totallen-=citymap[s][i].l;
                        totalcast-=citymap[s][i].t;
                }
        }
}

int main()
{
        int i,j;
        scanf("%d %d %d",&k,&n,&r);
        for(i=0;i<r;i++)
        {
                int s;road r;
                scanf("%d",&s);
                scanf("%d",&r.d);
                scanf("%d",&r.l);
                scanf("%d",&r.t);
                if(s!=r.d)
                        citymap[s].push_back(r);//类似于元素入队,只不过这里的元素是结构体
        }
        for(i=0;i<110;i++)
            for(j=0;j<10100;j++)
                minl[i][j]=1 << 30;
        memset(visit,0,sizeof(visit));
        visit[1]=1;
        dfs(1);
        if(minlen<(1 << 30))
                printf("%d\n",minlen);
        else
                printf("-1\n");



    return 0;
}

猜你喜欢

转载自blog.csdn.net/intelligentgirl/article/details/81325119