zoukankan      html  css  js  c++  java
  • [USACO08JAN]Telephone Lines

    嘟嘟嘟

    题意概括一下,就是在无向图上求一条1到n的路径,使路径上第k + 1大的边权尽量小。

    考虑dp,令dp[i][j] 表示走到节点 i,路线上有 j 条电话线免费时,路径上最贵的电缆花费最小是多少。则对于一条从u到v,长度为w的边,转移方程是:

        1.这条电缆要付费:dp[v][p] = min(dp[v][p], max(dp[u][p], w))

        2.这条电缆免费:dp[v][p + 1] = min(dp[v][p +1], dp[u][p])

    不过这是在图上dp,转移不能保证无后效性,因此我们可以利用spfa或dijkstra使dp有一个合理的顺序,因为最短路算法跑出来的是一个DAG,而dp状态之间的转移实质上就是在一个DAG上转移。

    因为spfa他死了,所以我就用dijkstra写:考虑当前的“最短路”,不是单纯的dis,而是当前最优的dp[i][j],因此我们要开一个结构体优先队列,里面有dp[i][j], i 和 j。然后按dp[i][j]排序。

    另外朴素的dijkstra是如果节点u出队了就不在入队,然而这道题需要开两维,in[i][j]表示节点 i ,j 个电话线免费的这个状态是否出队过。

    具体看代码吧,挺好懂。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a) memset(a, 0, sizeof(a))
    15 typedef long long ll;
    16 typedef double db;
    17 const int INF = 0x3f3f3f3f;
    18 const db eps = 1e-8;
    19 const int maxn = 1e3 + 5;
    20 inline ll read()
    21 {
    22     ll ans = 0;
    23     char ch = getchar(), last = ' ';
    24     while(!isdigit(ch)) {last = ch; ch = getchar();}
    25     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    26     if(last == '-') ans = -ans;
    27     return ans;
    28 }
    29 inline void write(ll x)
    30 {
    31     if(x < 0) x = -x, putchar('-');
    32     if(x >= 10) write(x / 10);
    33     putchar(x % 10 + '0');
    34 }
    35 
    36 int n, p, k;
    37 vector<int> v[maxn], c[maxn];
    38 
    39 struct Node
    40 {
    41     int _dp, nod, p;
    42     bool operator < (const Node& other)const
    43     {
    44         return _dp > other._dp;
    45     }
    46 };
    47 int dp[maxn][maxn];
    48 bool in[maxn][maxn];
    49 
    50 void dijkstra(int s)
    51 {
    52     for(int i = 1; i <= n; ++i)
    53         for(int j = 0; j <= n; ++j) dp[i][j] = INF;
    54     dp[s][0] = 0;
    55     priority_queue<Node> q;
    56     q.push((Node){dp[s][0], s, 0});
    57     while(!q.empty())
    58     {
    59         int now = q.top().nod, p = q.top().p; q.pop();
    60         if(in[now][p]) continue;        
    61         in[now][p] = 1;
    62         for(int i = 0; i < (int)v[now].size(); ++i)
    63         {
    64             int to = v[now][i];
    65             if(dp[to][p] > max(dp[now][p], c[now][i]))
    66             {
    67                 dp[to][p] = max(dp[now][p], c[now][i]);
    68                 q.push((Node){dp[to][p], to, p});
    69             }
    70             if(p < k && dp[to][p + 1] > dp[now][p])
    71             {
    72                 dp[to][p + 1] = dp[now][p];
    73                 q.push((Node){dp[to][p + 1], to, p + 1});
    74             }
    75         }
    76     }
    77     write(dp[n][k] == INF ? -1 : dp[n][k]); enter;
    78 }
    79 
    80 int main()
    81 {
    82     n = read(); p = read(); k = read();
    83     for(int i = 1; i <= p; ++i)
    84     {
    85         int x = read(), y = read(), co = read();
    86         v[x].push_back(y); c[x].push_back(co);
    87         v[y].push_back(x); c[y].push_back(co);
    88     }
    89     dijkstra(1); 
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    SP笔记:交叉实现七行并成一行
    HTML tag 学习
    操作哈希表
    Efficient bipedal robots based on passivedynamic walkers
    Pushing People Around
    ZEROMOMENT PONTTHIRTY FIVE YEARS OF ITS LIFE

    Active Learning for RealTime Motion Controllers
    Accelerometerbased User Interfaces for the Control of a Physically Simulated Character
    Dynamic Response for Motion Capture Animation
  • 原文地址:https://www.cnblogs.com/mrclr/p/9598604.html
Copyright © 2011-2022 走看看