POJ 3411 Paid Roads 简单DFS

题目链接:http://poj.org/problem?id=3411

题目大意:

  1. 有n座城市和m(1<=n,m<=10)条路。现在要从城市1到城市n。 
  2. 有些路是要收费的,从a城市到b城市,如果之前到过c城市,那么只要付P的钱,如果没有去过就付R的钱。求的是最少要花多少钱。 
  3. 注意:路径是有向的。
  4. 这题难点在于“城市与城市之间可能存在多条路径”:

    1、  输入数据时可能会出现多条 从城市a到城市b的路径信息,但是费用有所差别;

    2、  对于 从城市a到城市b 的同一条路径,允许重复走。

     
分析: 
  1.  因最多有10个城市,那么我们必须防范出现环自转的现在,显然3个城市可以出现环的现象。。那么假设走10个城市且出现了3个环, 
  2.  那么一个城市最多被利用3次,所以vis[u]<=3;
  3. 在同一个环路重复走才会真正增加费用。但是标记环路是很麻烦的,那么能不能根据某一条路或某一个城市重复走过的次数来判断当前所走的方案已经出现了环路? 答案是可以的。同一条路可以重复走,但是不能无限重复走,重复的次数是有限的。那么应该重复多少次才合理?这与m值有关。题目的m值范围为<=10,那么当人一个城市被到达的次数若  >3次(不包括3),所走的方案必然出现了环路。因此只需把bool vist[] 修改为 int vist[] 进行标记,本题就能解决了。
  4. 代码如下
    /*AC*/
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    struct edge{
        int a, b;
        int c, p, r;
    };
    
    const int INF = 1e9;
    edge a[11];
    int vis[11];
    int n, m;
    int mincost;
    
    void DFS(int from, int cost){
        if(from == n && cost < mincost){
            mincost = cost;
            return;
        }
        for(int i=1; i<=m; i++){
            if(a[i].a == from && vis[a[i].b]<= 3){
                vis[a[i].b]++;
                if(vis[a[i].c])
                    DFS(a[i].b, cost+a[i].p);
                else DFS(a[i].b, cost+a[i].r);
                vis[a[i].b]--;
            }
        }
    }
    
    int main(){
        while(scanf("%d %d", &n, &m) != EOF){
            for(int i=1; i<=m; i++)
                scanf("%d %d %d %d %d", &a[i].a, &a[i].b, &a[i].c, &a[i].p, &a[i].r);
            memset(vis, 0, sizeof(vis));
            mincost = INF;
            DFS(1, 0);
            if(mincost == INF)
                puts("impossible");
            else printf("%d\n", mincost);
        }
        return 0;
    }
    





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值