CCF 201712-5-商路 30分。。。枯了

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/rsy56640/article/details/88606431

第一个做的第五道题,其实我觉得我写的还不错的。。。
题目,思路,数据,代码见下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我的思路

按照拓扑排序DP
用S[i]表示 i 的最大价值,那么有
S [ i ] = m a x i j { S [ j ] + v [ i ] ( f [ i ] d i j ) 2 } S[i] = max_{i\to j} \{ S[j] + v[i] - (f[i] - d_{ij})^2 \}
中间做了一点优化,貌似是拖慢了时间。但其实有多种优化思路,主要根据矩阵是稀疏还是稠密,我做的优化比较折中。比如缓存了一些路径上的距离等,但结果貌似是省了内存,但是TLE。。。

Sample

样例输入
1
12
0 0 10 30
1 10 10 11
1 100 10 10
2 20 10 7
2 5 10 9
4 8 5 1
5 5 5 4
7 5 1 1
3 1 200 1
6 3 22 22
9 10 99 0
11 10 6 8
样例输出
224
样例输入
10
10
0 0 981021 2878
1 2982 103544 16423
2 9309 1146606 60
1 9632 339699 4022
1 4859 1050430 27644
4 7152 1016794 8381
2 691 202924 1579
5 682 312623 1947
1 5622 434383 1966
1 1036 337962 4867
10
0 0 613160 4178
1 6039 530965 36077
1 2641 588435 10697
2 8015 1773940 21360
2 9456 1536141 20760
3 1540 1069223 6060
3 4132 1802960 9712
4 1295 338084 630
4 5977 858393 3942
5 1981 1569807 8875
10
0 0 3297948 29281
1 2838 4499071 56444
2 1723 5082712 58167
3 6932 1899951 86996
4 6111 4673596 39622
5 4854 1283153 52866
6 1600 3076850 58518
7 2887 3936856 44586
8 9662 1653482 1115
9 6359 1438146 7533
10
0 0 3827584 9067
1 1114 1938309 90351
2 1913 3135879 31961
3 210 3118784 55465
4 6982 1115456 4482
5 4326 2504229 8147
6 3567 1296569 21072
6 857 3723988 867
7 2726 1349738 682
6 2569 1465079 9994
10
0 0 4152770 20839
1 3728 1993622 104795
2 3358 1563274 31216
3 6794 2231093 43445
4 2197 2316621 7602
5 1174 2985157 7136
6 8333 103275 6346
6 5129 3083322 3511
7 469 2368248 9692
7 5732 3765843 8563
10
0 0 3091416 127451
1 2323 3358598 10828
2 8139 3723827 15116
3 9725 2486973 25964
4 1954 2821451 18368
5 8257 3938729 32443
6 2554 4006939 13576
6 5881 511102 9605
7 7999 1954660 1148
7 3260 1916815 8710
10
0 0 366406 31967
1 7426 2566312 2237
1 654 2294113 5913
2 8186 893528 10662
2 6453 1512505 13321
4 6429 616635 6615
6 5842 2578315 14449
5 3568 2988564 9781
6 1704 1044306 9036
7 4747 155934 4217
10
0 0 2481887 67676
1 2514 2068792 41590
2 5134 2460668 181
1 608 1693903 5729
2 2202 2804903 37359
5 611 1673964 6522
6 429 1245126 10648
6 7898 358662 6483
7 4194 1315545 8960
6 1193 224838 7332
10
0 0 3403835 116677
1 77 2005502 44152
2 2913 3325129 47250
2 8094 2319341 37
3 3750 458636 52717
5 8465 1635392 21518
6 9440 1757959 2079
6 8555 2306608 4397
6 5530 2658501 440
7 1594 1833614 690
10
0 0 1477756 44072
1 8380 3425538 18191
2 7951 978970 6357
1 2602 184752 6671
3 725 2947560 1525
5 1314 3589295 39573
6 1755 1675874 6532
6 8848 2470638 3789
7 1620 2129738 9070
7 9509 2363613 6569
样例输出
970205
613151
0
4682720
3959657
2626087
19106
0
1522734
5999689

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <iterator>
#include <algorithm>
#include <stack>
using namespace std;

inline int read_int() { int a; scanf("%d", &a); return a; }
inline void outd(int x) { printf("%d", x); }
inline void outdn(int x) { printf("%d\n", x); }
inline void outn() { printf("\n"); }

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(NULL);

    int T = read_int();
    while (T--)
    {
        int n = read_int();
        // ref[] : the number of children, used for topology sorting.
        // S[]   : the max value of the cities.
        vector<int> uu(n + 1), ss(n + 1), vv(n + 1), ff(n + 1), ref(n + 1);
        vector<long long> S(n + 1);
        vector<unordered_map<int, int> > distance(n + 1);
        vector<unordered_set<int> > reachable(n + 1);
        int u, s, v, f;
        for (int i = 1; i <= n; i++)
        {
            scanf("%d %d %d %d", &u, &s, &v, &f);
            uu[i] = u;
            ss[i] = s;
            vv[i] = v;
            ff[i] = f;
            if (u != 0)
            {
                distance[u][i] = s; // dis[0] has one element, dis[0][1] = 0.
                reachable[u].insert(i);
                ref[u]++;
            }
        }
        ref[0] = 0;
        // preserve the succeeding nodes.
        vector<unordered_set<int> > next = reachable;
        // compute reachable[][]
        for (int i = 0; i < n - 2; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                unordered_set<int>& j_to = reachable[j];
                const int unreach_size = n - 1 - j_to.size();
                int new_reach_size = 0;
                for (int k = 1; k <= n; k++)
                {
                    if (j == k || unreach_size == new_reach_size || j_to.count(k)) continue;
                    for (int t = 1; t <= n; t++)
                        if (j_to.count(t) && reachable[t].count(k))
                        {
                            j_to.insert(k);
                            new_reach_size++;
                            break;
                        }
                }
            }
        }
        // DP: S[i] = max { S[j] + v[i] - (f[i] - dis[i][j])^2 }, where i to j.
        // topology sorting to determine the next to be computed.
        stack<int> stk;
        for (int i = 1; i <= n; i++)
            if (ref[i] == 0)
                stk.push(i);
        while (!stk.empty())
        {
            const int i = stk.top(); stk.pop();
            int ui = uu[i];
            if (--ref[ui] == 0) // note that ref[0] == 0
                stk.push(ui);
            // begin DP
            const unordered_set<int>& reach_set = reachable[i];
            for (unordered_set<int>::const_iterator it = reach_set.cbegin(); it != reach_set.cend(); ++it)
            {
                const int j = *it;
                int dij = 0, cur_pos = j;
                // get dij
                const unordered_set<int>& i_next = next[i];
                for (unordered_set<int>::const_iterator i_next_it = i_next.cbegin(); i_next_it != i_next.cend(); ++i_next_it)
                {
                    const int inext = *i_next_it;
                    if (inext == j)
                    {
                        distance[i][j] = dij = ss[inext];
                        break;
                    }
                    if (reachable[inext].count(j))
                    {
                        distance[i][j] = dij = distance[inext][j] + ss[inext];
                        break;
                    }
                }
                const long long delta = ff[i] - dij;
                S[i] = max(S[i], S[j] + vv[i] - delta * delta);
            }
        }
        long long result = 0;
        for (int i = 1; i <= n; i++)
            result += S[i];
        printf("%llu\n", (result % (unsigned long long)1e18));
    }
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/rsy56640/article/details/88606431