DFS专题之北大百炼1724

  1. 先给出源码
//AC 
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
int K,N,R;

//面向对象的思想 --> 将路的信息抽象为一个结构体,然后存储 
struct Road {
int d,L,t;//  destination    length  toll 
};
vector<Road>  cityMap[110]; //邻接表。cityMap[i]是从点i有路连到的城市集合 

int minLen = 1 << 30; //当前找到的最优路径的长度
int totalLen; //正在走的路径的长度
int totalCost ; //正在走的路径的花销
int visited[110]; //城市是否已经走过的标记
int minL[110][10100]; //minL[i][j]表示从1到i点的,花销为j的最短路的长度

void Dfs(int s) //从 s开始向N行走 
{
    if( s == N )//如果到达N 
    {
       minLen = min(minLen,totalLen);//求最短路径 
        return ; 
    }
    for( int i = 0 ;i < cityMap[s].size(); ++i ){//遍历所有连通节点 
        int d = cityMap[s][i].d; //s 有路连到d 
        if(! visited[d] ) {//若d未被访问 
            int cost = totalCost + cityMap[s][i].t; //记住 cityMap[s][i]存储的是Road 
            if( cost > K) 
                continue;//这里并不是return!!! 
            if( totalLen + cityMap[s][i].L >= minLen || totalLen + cityMap[s][i].L >= minL[d][cost])
             continue;
            totalLen += cityMap[s][i].L; 
            totalCost += cityMap[s][i].t;
            minL[d][cost] = totalLen;
            visited[d] = 1; 
            Dfs(d);

            //下面是回溯的过程!!! ---->  上面的节点d已经走过,但是仍然不能保证后面的路径计算过程中
            //用不到节点d,所以一定要给节点d回溯!!这是本题的关键。 
            visited[d] = 0; 
            totalCost -= cityMap[s][i].t; 
            totalLen -= cityMap[s][i].L; 
            }
        }
}
int main()
{
    cin >>K >> N >> R;//最多钱  城市数  路数 
    for( int i = 0;i < R; ++ i){
        int s; // 一条路的始发点 
        Road r; //结构体r  代表一条路 Road 
        cin >> s >> r.d >> r.L >> r.t; 
        if( s != r.d ) //如果始发点和到达点不是同一城市   --- 添加到cityMap中 
        cityMap[s].push_back(r); 
    }
    for( int i = 0;i < 110; ++i ) 
    {
        for( int j = 0; j < 10100; ++ j ) 
        minL[i][j] = 1 << 30;
    }
    memset(visited,0,sizeof(visited));
    totalLen = 0;
    totalCost = 0;
    visited[1] = 1;
    minLen = 1 << 30;
    Dfs(1);
    if( minLen < (1 << 30))
        cout << minLen << endl;
    else
        cout << "-1" << endl;
}
/*
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
**/
  1. 需要解决的问题
    • 1)vector