• poj 1724 ROADS 解题报告


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

    题目意思:给出一个含有N个点(编号从1~N)、R条边的有向图。Bob 有 K 那么多的金钱,需要找一条从顶点1到顶点N的路径(每条边需要一定的花费),前提是这个总花费  <= K.

          首先这里很感谢 yunyouxi0 ,也就是我们的ACM队长啦~~~,他一下子指出了我的错误——存储重边的错误。这条题卑鄙的地方是,有重边,discuss 中的数据过了也不一定会AC啦。大家不妨试试这组数据(队长深情奉献^_^)

         2

         2 

         2 

        1  2   2   3

        1  2   3   2

         ans:   3

          用邻接表来存储就可以解决这个问题啦。看了差不多整天的邻接表,终于看懂了,大感动啊^__^。对于初次使用的我(或者其他也是第一次接触的读者),希望这幅图能帮大家理解理解~~~~

         

       我用Sample 来解释这幅图  

    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

      建立一个邻接表

     struct adj_table // 邻接表
    {
    int next, D, L, T;
    }node[M];

         首先这个F[i] 表示对于编号为 i 这个 点中跟它相邻的点有多少个,也就是表头! 

         那些0、3、1、...、5的意思实质就是第几行输入,假设是3 5 2 0, 是图中的数字 5了,对于3这个点来说,如果还有一条从点3出发的边,那么下一次插入就从这个 5 开始。

         可能我还是说得不清不楚啦~~~,结合这个运行结果还有上面那幅本人呕心沥血图来看,是不是一下子豁然开朗呢?注意 j = 3(v = 3) 之后,下一个点是node[3].next ,也就是 0(v = 2),由于我们在插入的时候,node[3].D 已经把目标节点记录下来了,还有长度和花费,所以不断往返的时候,就能求出所有跟 j = 3 的所有相邻节点了(再下一个是 node[0].next ,为-1 就停止了,代表已经到达头结点:编号为1的点,刚好对于节点1来说,  2, 3 就是跟它邻接的点,由于是回溯回去的,所以先输出3, 再输出2)

           

         (first 点 6 结束了,因为从6出发没有路!)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 const int INF = 10000000;
     7 const int M = 10000 + 5;
     8 const int maxn = 100 + 5;
     9 struct adj_table    // 邻接表
    10 {
    11     int next, D, L, T;
    12 }node[M];      // 不要开小了!!!写成maxn会runtime error
    13 
    14 int F[maxn];  // 表头
    15 int vis[maxn];
    16 
    17 int K, N, R, flag, minlen;
    18 
    19 void dfs(int head, int r, int l)
    20 {
    21     if (l > minlen)    // 剪枝,防止TLE的关键
    22         return;
    23     if (head == N && r >= 0)
    24     {
    25         flag = 1;
    26         minlen = min(minlen, l);
    27         return;
    28     }
    29     for (int i = F[head]; i != -1; i = node[i].next)
    30     {
    31         int v = node[i].D;
    32         if (!vis[v]&& r-node[i].T >= 0) // 未走过+费用足
    33         {
    34             vis[v] = 1;
    35             dfs(v, r-node[i].T, l+node[i].L);  // 注意:不是r-node[v].T和l+node[v].L, 因为是指向下一个顶点, v是当前顶点
    36             vis[v] = 0;
    37         }
    38     }
    39 }
    40 
    41 int main()
    42 {
    43     while (scanf("%d%d%d", &K, &N, &R) != EOF)
    44     {
    45         int s, d, l, t;
    46         int count = 0;
    47         memset(vis, 0, sizeof(vis));
    48         memset(F, -1, sizeof(F));
    49         for (int i = 0; i < R; i++)
    50         {
    51             scanf("%d%d%d%d", &s, &d, &l, &t);
    52             node[count].next = F[s];
    53             node[count].D = d, node[count].L = l, node[count].T = t;
    54             F[s] = count++;
    55         }
    56         vis[1] = 1;
    57         minlen = INF, flag = 0;
    58         dfs(1, K, 0);
    59         printf("%d
    ", !flag ? -1 : minlen);
    60     }
    61     return 0;
    62 }

         

  • 相关阅读:
    SQL Server如何固定执行计划
    领导修炼
    content management system
    npm和bower
    web开发workflow
    偏执狂
    website project team member 角色及开发过程概念图
    website architecture
    王道霸道
    design pattern及其使用
  • 原文地址:https://www.cnblogs.com/windysai/p/3878592.html
Copyright © 2020-2023  润新知