算法笔记 深搜

算法中里面的一个函数名,如c++中的vector头文件里面就有这个push_back函数,在vector类中作用为在vector尾部加入一个数据。

string中也有这个函数,作用是字符串之后插入一个字符。
如果是指标准模板库(stl)中容器的一般pushback()操作函数,那么是指在容器尾端插入一项数据,比如
vector<int> a(10);
a.pushback(10);
那么a的尾端,同时也是唯一一个数据a[0]就会为设置为10。

题目:

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




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 
Source

CEOI 1998

解答:


/*
//POJ1724
//ROADS 深度优先
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int K,N,R;//N个城市
struct Road{
    int d,L,t;
};
//用邻接表存放整条路的信息
vector< vector<Road> >G(110);

int minLen;//存储目前找过的最佳的路径长度
int totalLen;//已经探索的路径已经走了多长
int totalCost;//长在走的路已经花了多少钱
int visited[110];//标志数组,表示一个城市是否已经走过 

void dfs(int s){
    if(s==N){
        minLen=min(minLen,totalLen);
        return;
    }
    for(int i=0;i<G[s].size();++i){
        Road r=G[s][i];
        if(totalCost+r.t>K)
            continue;
        if(!visited[r.d]){
            totalLen+=r.L;
            totalCost+=r.t;
            visited[r.d]=1;
            dfs(r.d);
            visited[r.d]=0;
            totalLen-=r.L;
            totalCost-=r.t;
        }
    }
}

int main(){
    cin>>K>>N>>R;
    for(int i=0;i<R;i++){
        int s;
        Road r;
        cin>>s>>r.d>>r.L>>r.t;//起点s,终点d,边的长的L,边的过路费t
        if(s!=r.d){
            G[s].push_back(r);
        }
    }
    //初始化
    memset(visited,0,sizeof(visited));
    totalLen=0;
    minLen=1<<30;
    totalCost=0;
    visited[1]=1;
    dfs(1);
    if(minLen<(1<<30)){
        cout<<minLen<<endl;
    }else
        cout<<"-1"<<endl;
    return 0;
} //超时

*/
/*
 //POJ1724
//ROADS 深度优先
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int K,N,R;//N个城市
struct Road{
    int d,L,t;
};
//用邻接表存放整条路的信息
vector< vector<Road> >G(110);

int minLen;//存储目前找过的最佳的路径长度
int totalLen;//已经探索的路径已经走了多长
int totalCost;//长在走的路已经花了多少钱
int visited[110];//标志数组,表示一个城市是否已经走过 

void dfs(int s){
    if(s==N){
        minLen=min(minLen,totalLen);
        return;
    }
    for(int i=0;i<G[s].size();++i){
        Road r=G[s][i];
        if(totalCost+r.t>K)
            continue;
        if(!visited[r.d]){
            if(totalLen+r.L>=minLen){//////////最优性剪枝:
                continue;//////////////////////(1)如果当前已经找到的最优路径长度为L,那么再继续搜索的过程中,总长度已经大于等于L的走法,就可以直接放弃,不用坚持到底
            } /////////////////////////////////很强的剪枝,效果拔群
            totalLen+=r.L;
            totalCost+=r.t;
            visited[r.d]=1;
            dfs(r.d);
            visited[r.d]=0;
            totalLen-=r.L;
            totalCost-=r.t;
        }
    }
}

int main(){
    cin>>K>>N>>R;
    for(int i=0;i<R;i++){
        int s;
        Road r;
        cin>>s>>r.d>>r.L>>r.t;//起点s,终点d,边的长的L,边的过路费t
        if(s!=r.d){
            G[s].push_back(r);
        }
    }
    //初始化
    memset(visited,0,sizeof(visited));
    totalLen=0;
    minLen=1<<30;
    totalCost=0;
    visited[1]=1;
    dfs(1);
    if(minLen<(1<<30)){
        cout<<minLen<<endl;
    }else
        cout<<"-1"<<endl;
    return 0;
} //可惜还是超时
*/ 

 //POJ1724
//ROADS 深度优先
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int K,N,R;//N个城市
struct Road{
    int d,L,t;
};
//用邻接表存放整条路的信息
vector< vector<Road> >G(110);
int minL[110][10010];///////////////////////////////////
int minLen;//存储目前找过的最佳的路径长度
int totalLen;//已经探索的路径已经走了多长
int totalCost;//长在走的路已经花了多少钱
int visited[110];//标志数组,表示一个城市是否已经走过 

//用mid[k][m]表示:走到城市k时总过路费为m的条件下,最优路径的长度。若在后续的搜索中,在此走到k时,如果总路费恰好为m,且此时的路径长度已经超过mid[k][m],则不必再走下去了。 

void dfs(int s){
    if(s==N){
        minLen=min(minLen,totalLen);
        return;
    }
    for(int i=0;i<G[s].size();++i){
        Road r=G[s][i];
        if(totalCost+r.t>K)
            continue;
        if(!visited[r.d]){
            if(totalLen+r.L>=minLen){
                continue;
            }

            /////////////////////////////////////////////////////////////可行性剪枝:
            if(totalLen+r.L>=minL[r.d][totalCost+r.t])///////////////////啥都不说了:
                continue;/////////////////////////////////////////////////加速超快!!
            minL[r.d][totalCost+r.t]=totalLen+r.L;////////////////////////

            totalLen+=r.L;
            totalCost+=r.t;
            visited[r.d]=1;
            dfs(r.d);
            visited[r.d]=0;
            totalLen-=r.L;
            totalCost-=r.t;
        }
    }
}

int main(){
    cin>>K>>N>>R;
    for(int i=0;i<R;i++){
        int s;
        Road r;
        cin>>s>>r.d>>r.L>>r.t;//起点s,终点d,边的长的L,边的过路费t
        if(s!=r.d){
            G[s].push_back(r);
        }
    }
    //初始化
    memset(visited,0,sizeof(visited));
    totalLen=0;
    minLen=1<<30;
    totalCost=0;
    visited[1]=1;//////////////////////////////////
    for(int i=0;i<110;i++){/////////////////////////
        for(int j=0;j<10010;j++){/////////////////
            minL[i][j]=1<<30;///////////////////////
        }//////////////////////////////////////////
    }////////////////////////////////////////////////
    dfs(1);
    if(minLen<(1<<30)){
        cout<<minLen<<endl;
    }else
        cout<<"-1"<<endl;
    return 0;
} 

原文地址:https://www.cnblogs.com/dourcer/p/8607481.html

时间: 2024-08-04 16:19:31

算法笔记 深搜的相关文章

【算法总结】深搜

算法总结-深搜 由于是深度优先,后进入的结点需要先读取,因此选取堆栈实现,在栈中保存从起始结点(状态)到当前结点的路径上的所有结点.一般用递归实现. 非递归框架 DFS() { 初始化栈 while (栈不为空 & 未找到目标结点) { 取栈顶元素扩展,扩展出的结点放回栈顶 } ...... } 递归框架 在深度优先搜索中,状态空间的图结构并不一定需要显式地保存下来. type node; void DFS(int depth) { for (node的每一个可行变化) { 改变node DFS

算法学习笔记 二叉树和图遍历—深搜 DFS 与广搜 BFS

图的深搜与广搜 马上又要秋招了,赶紧复习下基础知识.这里复习下二叉树.图的深搜与广搜.从图的遍历说起,图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其经典应用走迷宫.N皇后.二叉树遍历等.遍历即按某种顺序访问"图"中所有的节点,顺序分为: 深度优先(优先往深处走),用的数据结构是栈, 主要是递归实现: 广度优先(优先走最近的),用的数据结构是队列,主要是迭代实现: 对于深搜,由于递归往往可以方便的利

算法学习笔记(六) 二叉树和图遍历—深搜 DFS 与广搜 BFS

图的深搜与广搜 复习下二叉树.图的深搜与广搜. 从图的遍历说起.图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其经典应用走迷宫.N皇后.二叉树遍历等.遍历即按某种顺序訪问"图"中全部的节点,顺序分为: 深度优先(优先往深处走),用的数据结构是栈, 主要是递归实现. 广度优先(优先走近期的).用的数据结构是队列.主要是迭代实现. 对于深搜.因为递归往往能够方便的利用系统栈,不须要自己维护栈.所以通常实

深搜笔记

看搜索已经很久了,对于搜索的思想从原来的死记硬背到现在终于懂了一点其实也蛮不错吧,我自己先总结出来了几条关于在图里面深搜的几条方法,仅供参考: 首先:我们得知道深搜是什么,其次于广搜的区别是什么.然后又哪些模板 举一个深搜例子:red and black:这是初学者最常见到的题.对于这题我们所要考虑的就是一个'.'的个数,这个题先要找到@的位置,这个好办,直接: for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { if(map[i][j]=='@') }

hdu 5311 Hidden String dp o(n)算法 深搜

Hidden String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 857    Accepted Submission(s): 322 Problem Description Today is the 1st anniversary of BestCoder. Soda, the contest manager, gets

HDU ACM 1142 A Walk Through the Forest-&gt;SPFA算法+记忆化深搜

分析:找到吉米从办公室穿过森林回到家(也就是从点1到点2)的最短路径有多少条,其中要满足如果要走A到B这条路,那么就有从A到终点的距离都大于B到终点的距离. 解法:spfa算法+记忆化深搜 1.spfa求出从终点2到其他所有点的最短路 2.记忆化DFS从1开始向其他点深搜,最后结果就是dp[1]. #include<iostream> #include<queue> using namespace std; int u[2000002]; int v[2000002]; int w

算法-图是否为树(并查集或深搜)

今天做了一道很有意思的一道题,这道题虽然难度只是中等,但是里面涉及到的东西却是不少.其中,我在里面学习到了并查集这个东西,虽然不是很深刻,至少有一个印象:还有深搜,一直以来,深搜和广搜都是我的弱项,本文的理解是基于别人的博客:lintcode178. graph valid tree 图是否是树.我们来看看题 题意: 给出 n 个节点,标号分别从 0 到 n - 1 并且给出一个 无向 边的列表 (给出每 条边的两个顶点), 写一个函数去判断这张`无向`图是否是一棵树 样例: 给出n = 5 并

HDU1342 Lotto 【深搜】

应用 渗透问题 游戏中会用到. 动态连接 最近共同祖先 等价有限状态机 物理学Hoshen-Kopelman算法:就是对网格中的像素进行分块 Hinley-Milner多态类型推断 Kruskai最小生成树 Fortran等价语句编译 形态学开闭属性 Matlab中关于图像处理的bwlabel函数 渗透问题 一个N×N的矩阵,判断顶部和底部是否连通就是渗透问题. 下图中左侧的矩阵能渗透,右侧矩阵不能渗透. 渗透问题在电学.流体力学.社会交际中都有应用. 在游戏中可能需要生成一张地图,但是作为地图

【深搜加剪枝五】HDU 1010 Tempter of the Bone

Tempter of the BoneTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 64326    Accepted Submission(s): 17567 Problem Description The doggie found a bone in an ancient maze, which fascinated him a l