zoukankan      html  css  js  c++  java
  • HDU-2157-How many ways??

    • 广度优先搜索+动态规划
      Accepted 2157 0MS 1376K 1415B G++
      #include "bits/stdc++.h"
      using namespace std;
      typedef pair<int, int> PII;
      const int MAXN = 25;
      const int MOD = 1000;
      // dp[i][j]表示固定起点后到达i走了j步的情况数 
      int dp[MAXN][MAXN];
      bool mp[MAXN][MAXN];
      queue<PII> que;
      int n, m;
      void BFS(int k) {
          while (!que.empty()) {
              int u = que.front().first;
              int w = que.front().second;
              que.pop();
              if (w == k) {
                  break;
              }
              for (int v = 0; v < n; v++) {
                  if (mp[u][v] == false) continue;
                  // 每个状态只能入队一次 
                  if (dp[v][w + 1] == -1) {
                      que.push({v, w + 1});
                      dp[v][w + 1] = 0;
                  } 
                  dp[v][w + 1] = (dp[v][w + 1] + dp[u][w]) % MOD;
              }
          }
          while (!que.empty()) que.pop();
      }
      int main() {
          int u, v, w;
          while (scanf("%d%d", &n, &m) && (n || m)) {
              memset(mp, false, sizeof(mp));
              while (m--) {
                  scanf("%d%d", &u, &v);
                  mp[u][v] = true;
              }
              scanf("%d", &m);
              while (m--) {
                  memset(dp, -1, sizeof(dp));
                  scanf("%d%d%d", &u, &v, &w);
                  dp[u][0] = 1;
                  que.push({u, 0});
                  BFS(w);
                  if (dp[v][w] != -1) {
                      printf("%d
      ", dp[v][w]);
                  } else {
                      puts("0");
                  }
              }
          }
          return 0;
      }

      对于本题比较快,但是如果w大了就不再适用,运行时间飙升。

    • 矩阵快速幂 (看了大佬的代码之后敲的 https://www.cnblogs.com/hua-dong/p/7749902.html)
      Accepted 2157 109MS 1392K 1016 B G++
      #include "bits/stdc++.h"
      using namespace std;
      const int MOD = 1000;
      int n, m;
      struct Mat {
          int mat[25][25];
          Mat() {
              memset(mat, 0, sizeof(mat));
          }
          friend Mat operator * (Mat a, Mat b) {
              Mat c;
              for(int i = 0; i < n; i++)
              for(int j = 0; j < n; j++)
              for(int k = 0; k < n; k++)
              c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD;
              return c;
          }
      };
      Mat Mat_pow(Mat m, int k) {
          Mat ans;
          for(int i = 0; i < n; i++)
          ans.mat[i][i] = 1;
          while(k) {
              if(k & 1)
              ans = ans * m;
              m = m * m;
              k >>= 1;
          }
          return ans;
      }
      int main() {
          int u, v, k;
          while (scanf("%d%d", &n, &m) && (n || m)) {
              Mat mp, ans;
              for (int i = 0; i < m; i++) {
                  scanf("%d%d", &u, &v);
                  mp.mat[u][v] = 1;
              }
              scanf("%d", &m);
              for (int i = 0; i < m; i++) {
                  scanf("%d%d%d", &u, &v, &k);
                  ans = Mat_pow(mp, k);
                  printf("%d
      ", ans.mat[u][v]);
              }
          }
          return 0;
      }

      对于本题,这份代码的复杂度高于上面那份,那是因为本题数据较小。如果k很大,矩阵快速幂的方法一定是比较优的。虽然会矩阵快速幂,还是没看出来mp就是可以得到结果的矩阵,果然还是菜了。慢慢积累吧。

  • 相关阅读:
    .NET 操作XML
    C#常用操作类库五(电脑操作类)
    C#常用操作类库四(File操作类)
    C#常用操作类库一(验证类)
    RabbitMQ 学习
    redis 常用命令
    windows10配置redis一主二从三哨兵
    Oracle递归查询(查询当前记录所有父级或子级)
    echarts 中 柱图 、折线图、柱图层叠
    简单的前台登录
  • 原文地址:https://www.cnblogs.com/Angel-Demon/p/10696891.html
Copyright © 2011-2022 走看看