zoukankan      html  css  js  c++  java
  • 51nod1326 遥远的旅途(spfa+dp)

    题意:
    给出一个无向图,问从1到n是否存在一条长度为L的路径。
    n,m<=50,1<=路径长度<=10000,L<=10^18

    思路:
    改变一下思路,我们发现,假设从起点1走到终点N有一条路径的长度为a,假设它再往一条与终点相连的长为b的路径反复走无数次后使得路径长度到达了T,那么一定有(T-a)%(2*k)==0**T%(2*k)=a%(2*k),所以我们只需要看是否从1到N存在一条路径长度为d,使得d%(2*k)=t%(2*k)
    因为这个题目和模数有关,所以我们要把取摸的结果写入状态.
    dp[i][j]表示处于i节点,从一号点到i号点的花费和%(2*k)(选择的边权)等与k的最小花费.
    那么转移就是: dp[to][(j+quan)%mod]=min(dp[now][j]+quan)
    因为具有后效性,所以需要spfa.

     1 //这道题较多的参考了晚上的解法,在看懂之后自己又写了一遍
     2 //链接:https://blog.csdn.net/qq_33229466/article/details/77131289
     3 #include<cstdio>
     4 #include<queue>
     5 #include<string.h>
     6 using namespace std;
     7 typedef long long LL;
     8 
     9 const int maxn = 50 + 5, maxm = 2e4 + 5;
    10 int n, m, num, head[maxn];
    11 LL t, dp[maxn][maxm], inf = 2000000000000000000;
    12 bool vis[maxn][maxm];
    13 
    14 struct node { 
    15     int to, w, next;
    16 }edge[maxn * 2];
    17 queue<pair<int, int>>q;
    18 
    19 void add_edge(int u, int v, int w)
    20 {
    21     edge[++num].to = v; 
    22     edge[num].w = w; 
    23     edge[num].next = head[u]; 
    24     head[u] = num;
    25 }
    26 
    27 void spfa(int mod)
    28 {
    29     q.push(make_pair(1,0)); vis[1][0] = 1;
    30     while (!q.empty())
    31     {
    32         pair<int,int> u = q.front(); q.pop();
    33         int x = u.first, y = u.second;
    34         for (int i = head[x]; i; i = edge[i].next)
    35             if (dp[x][y] + edge[i].w < dp[edge[i].to][(y + edge[i].w) % mod])
    36             {
    37                 int nx = edge[i].to, ny = (y + edge[i].w) % mod;
    38                 dp[nx][ny] = dp[x][y] + edge[i].w;
    39                 if (!vis[nx][ny]) {
    40                     q.push(make_pair(nx, ny));
    41                     vis[nx][ny] = 1;
    42                 }
    43             }
    44         vis[x][y] = 0;
    45     }
    46 }
    47 
    48 int main()
    49 {
    50     int kase;
    51     scanf("%d", &kase);
    52     while (kase--)
    53     {
    54         memset(head, 0, sizeof(head));
    55         scanf("%d%d%lld", &n, &m, &t);
    56         num = 0;
    57         for (int i = 1; i <= m; i++)
    58         {
    59             int x, y, w;
    60             scanf("%d%d%d", &x, &y, &w);
    61             add_edge(x, y, w);
    62             add_edge(y, x, w);
    63         }
    64         int flag = 0;
    65         for (int i = 1; i <= num; i += 2)
    66             if (edge[i].to == 1 || edge[i + 1].to == 1)
    67             {
    68                 int w = edge[i].w * 2;
    69                 for (int j = 1; j <= n; j++) {
    70                     for (int k = 0; k < w; k++) {
    71                         dp[j][k] = inf;
    72                     }
    73                 }
    74                 dp[1][0] = 0;
    75                 spfa(w);
    76                 if (dp[n][t%w] <= t)
    77                 {
    78                     printf("Yes
    ");
    79                     flag = 1;
    80                     break;
    81                 }
    82             }
    83         if (!flag) printf("No
    ");
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    51nod1089(最长回文子串之manacher算法)
    51nod1088(最长回文子串)
    51nod1256(乘法逆元)
    51nod1085(01背包)
    51nod1079(中国剩余定理)
    数据的特征工程
    30种提高mysql处理速度的方法
    机器学习资料
    python3.6安装-windows
    python import sklearn出错 "ImportError: DLL load failed: 找不到指定的模块。
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9489832.html
Copyright © 2011-2022 走看看