【练习赛补题】问题 D: 最短路径问题 hdu3790【dfs】

题目描述

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。

输入

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)

输出

输出 一行有两个数, 最短距离及其花费。

样例输入

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

样例输出

9 11
思路:题面已经讲的很清楚了,需要注意,路径有两个权值,用dijsktra就可以解决,只不过我自己被提示带歪,用了dfs来写这道题,递归又成了硬伤,昨天才被吐槽过,不会递归还用什么dfs。。。
自己错的地方如下:
1:初始化。标记数组应该全部初始化为不能通过,即-1,输入边时,能通过一条边就将这条边初始化为0.
2:递归出口。到达终点并不是结束条件,只有点全部搜索完才结束,然后回溯。
3:更新最短距离和花费的条件。有两种情况:一种是最短距离相等时,比较花费,一种是最短距离不等,直接比较最短距离。
#include<stdio.h>
#include<string.h>
#define N 1010
#define inf 0x3f3f3f3f
int n,m,ans,min1,min2,cost,head,tail,sum1,sum2;
int book[N][N];
int dis[N],w[N];
struct node{
    int len,cost;
};
node e[N][N];
void dfs(int x,int c,int d)
{
    int y,i;
    if(x > n)
        return ;
    if(x == tail)
    {
        if(d < min1||d == min1 && c < min2)
        {
            min1 = d;
            min2 = c;
        }
    }
    for(i = 1; i <= tail; i ++)
        if(book[x][i]==0)
        {
            book[x][i] = -1;
            dfs(i,c+e[x][i].cost,d+e[x][i].len);
            book[x][i] = 0;
        }
    return;
}
int main()
{
    int i,j,t1,t2,t3,t4,u;
    while(scanf("%d%d",&n,&m),(n+m)!=0)
    {
        memset(book,-1,sizeof(book));
        for(i = 1; i <= m; i ++)
        {
            scanf("%d%d%d%d",&t1,&t2,&t3,&t4);
            e[t1][t2].len  = t3;
            e[t2][t1].len = t3;
            e[t1][t2].cost = t4;
            e[t2][t1].cost = t4;
            book[t1][t2] = 0;
            book[t2][t1] = 0;
        }
        scanf("%d%d",&head,&tail);
        min1 = min2 = inf;
        dfs(head,0,0);
        printf("%d %d
",min1,min2);
    }
    return 0;
 } 
原文地址:https://www.cnblogs.com/hellocheng/p/7405052.html