solution.md 6.3 KB
Newer Older
每日一练社区's avatar
每日一练社区 已提交
1
# 大臣的旅费
F
fix bug  
feilong 已提交
2

3
**问题描述**
F
fix bug  
feilong 已提交
4

每日一练社区's avatar
每日一练社区 已提交
5 6 7 8 9 10 11 12 13 14
很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。  

为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。  

J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。  

聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。  

J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?  

15
**输入格式**
F
fix bug  
feilong 已提交
16

每日一练社区's avatar
每日一练社区 已提交
17 18 19 20 21 22 23 24
输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数

城市从1开始依次编号,1号城市为首都。

接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)

每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。

25
**输出格式**
F
fix bug  
feilong 已提交
26

每日一练社区's avatar
每日一练社区 已提交
27 28
输出一个整数,表示大臣J最多花费的路费是多少。

29
**样例输入1**
F
fix bug  
feilong 已提交
30

每日一练社区's avatar
每日一练社区 已提交
31 32 33 34 35 36 37
```
5
1 2 2
1 3 1
2 4 5
2 5 4
```
38
**样例输出1**
F
fix bug  
feilong 已提交
39

每日一练社区's avatar
每日一练社区 已提交
40 41 42
```
135
```
43
**输出格式**
F
fix bug  
feilong 已提交
44

每日一练社区's avatar
每日一练社区 已提交
45 46 47 48
```
大臣J从城市4到城市5要花费135的路费。
```

每日一练社区's avatar
每日一练社区 已提交
49
下面<font color="red">错误</font>的一项是?
每日一练社区's avatar
每日一练社区 已提交
50

每日一练社区's avatar
每日一练社区 已提交
51
## aop
F
fix bug  
feilong 已提交
52

每日一练社区's avatar
每日一练社区 已提交
53
### before
F
fix bug  
feilong 已提交
54

每日一练社区's avatar
每日一练社区 已提交
55 56 57 58 59
```cpp
#include <bits/stdc++.h>
using namespace std;
```
### after
F
fix bug  
feilong 已提交
60

每日一练社区's avatar
每日一练社区 已提交
61 62 63 64 65
```cpp

```

## 答案
F
fix bug  
feilong 已提交
66

每日一练社区's avatar
每日一练社区 已提交
67
```cpp
每日一练社区's avatar
每日一练社区 已提交
68
struct edge
每日一练社区's avatar
每日一练社区 已提交
69
{
每日一练社区's avatar
每日一练社区 已提交
70 71 72 73 74 75 76 77 78 79 80 81
    int to, cost;
};
vector<vector<edge>> G;
vector<bool> vst;
int n;
int ans, dis;
void dfs(int u, int d)
{
    vst[u] = true;
    if (d > dis)
        ans = u, dis = d;
    for (int i = 0; i < G[u].size(); i++)
每日一练社区's avatar
每日一练社区 已提交
82
    {
每日一练社区's avatar
每日一练社区 已提交
83 84 85
        int son = G[u][i].to;
        if (!vst[son])
            dfs(son, G[u][i].cost);
每日一练社区's avatar
每日一练社区 已提交
86
    }
每日一练社区's avatar
每日一练社区 已提交
87 88 89 90 91 92
    vst[u] = false;
}
int find(int u)
{
    ans = dis = 0;
    dfs(u, 0);
每日一练社区's avatar
每日一练社区 已提交
93 94
    return ans;
}
每日一练社区's avatar
每日一练社区 已提交
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
int main()
{
    scanf("%d", &n);
    G.resize(n + 5), vst.resize(n + 5);
    for (int i = 1; i < n; i++)
    {
        int p, q, d;
        scanf("%d %d %d", &p, &q, &d);
        G[p].push_back(edge{q, d});
        G[q].push_back(edge{p, d});
    }
    int x = find(1), y = find(x);
    printf("%d", dis * (dis + 1) / 2 + 10 * dis);
    return 0;
}
每日一练社区's avatar
每日一练社区 已提交
110 111 112
```
## 选项

F
fix bug  
feilong 已提交
113

每日一练社区's avatar
每日一练社区 已提交
114
### A
F
fix bug  
feilong 已提交
115

每日一练社区's avatar
每日一练社区 已提交
116
```cpp
每日一练社区's avatar
每日一练社区 已提交
117 118 119
const int maxd = 10000 + 50;

struct Point
每日一练社区's avatar
每日一练社区 已提交
120
{
每日一练社区's avatar
每日一练社区 已提交
121 122 123 124 125 126 127 128 129 130
    map<int, int> m;
    int status;
} p[maxd];

int r = 0, gps;

void f(int x, int ctn)
{
    p[x].status = 1;
    for (map<int, int>::iterator it = p[x].m.begin(); it != p[x].m.end(); it++)
每日一练社区's avatar
每日一练社区 已提交
131
    {
每日一练社区's avatar
每日一练社区 已提交
132 133 134 135 136 137 138 139 140
        if (p[it->first].status == 1)
            continue;
        f(it->first, ctn + it->second);
    }
    p[x].status = 0;
    if (r < ctn)
    {
        r = ctn;
        gps = x;
每日一练社区's avatar
每日一练社区 已提交
141
    }
每日一练社区's avatar
每日一练社区 已提交
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
}

int main()
{
    int n, i, x, y, l;
    cin >> n;
    for (i = 0; i < n - 1; i++)
    {
        cin >> x >> y >> l;
        p[x].m[y] = l;
        p[y].m[x] = l;
    }

    f(1, 0);

    f(gps, 0);

    cout << (21 + r) * r / 2;
    return 0;
每日一练社区's avatar
每日一练社区 已提交
161 162 163 164
}
```

### B
F
fix bug  
feilong 已提交
165

每日一练社区's avatar
每日一练社区 已提交
166
```cpp
每日一练社区's avatar
每日一练社区 已提交
167 168 169 170 171 172 173 174 175 176
#define _for(i, a, b) for (int i = a; i < b; i++)
#define _unfor(i, a, b) for (int i = a; i >= b; i--)
#define RI(a) scanf("%d", &a)
using namespace std;
typedef long long LL;
int d[111111], n, vis[111111], maxh = 0, p_h[111111], ans = 0;
vector<int> son[111111], G[111111], h_p[111111];
map<pair<int, int>, int> W;

int main()
每日一练社区's avatar
每日一练社区 已提交
177
{
每日一练社区's avatar
每日一练社区 已提交
178 179
    RI(n);
    _for(i, 1, n)
每日一练社区's avatar
每日一练社区 已提交
180
    {
每日一练社区's avatar
每日一练社区 已提交
181 182 183 184 185 186 187 188 189
        int a, b, c;
        RI(a);
        RI(b);
        RI(c);
        G[a].push_back(b);
        G[b].push_back(a);
        pair<int, int> pr(a > b ? a : b, a > b ? b : a);
        W[pr] = c;
    }
每日一练社区's avatar
每日一练社区 已提交
190

每日一练社区's avatar
每日一练社区 已提交
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
    queue<int> q;
    q.push(1);
    h_p[0].push_back(1);
    while (!q.empty())
    {
        int v = q.front(), len = G[v].size();
        q.pop();
        vis[v] = 1;
        _for(k, 0, len)
        {
            int e = G[v][k];
            if (!vis[e])
            {
                vis[e] = 1;
                son[v].push_back(e);
                q.push(e);
                maxh = max(maxh, p_h[e] = p_h[v] + 1);
                h_p[p_h[e]].push_back(e);
            }
        }
    }
每日一练社区's avatar
每日一练社区 已提交
212

每日一练社区's avatar
每日一练社区 已提交
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
    _unfor(h, maxh, 0)
    {
        int len = h_p[h].size();
        _for(k, 0, len)
        {
            int i = h_p[h][k], _max = 0, _cmax = 0;
            int len2 = son[i].size();
            _for(k2, 0, len2)
            {
                int j = son[i][k2], t;
                pair<int, int> pr(i > j ? i : j, i > j ? j : i);
                t = W[pr] + d[j];
                if (t > _cmax)
                    if ((_cmax = t) > _max)
                        swap(_max, _cmax);
                ans = max(ans, _max + _cmax);
            }
            d[i] = _max;
每日一练社区's avatar
每日一练社区 已提交
231 232
        }
    }
每日一练社区's avatar
每日一练社区 已提交
233
    cout << (LL)(ans + 1) * ans / 2 + ans * 10 << endl;
每日一练社区's avatar
每日一练社区 已提交
234 235 236 237
}
```

### C
F
fix bug  
feilong 已提交
238

每日一练社区's avatar
每日一练社区 已提交
239
```cpp
每日一练社区's avatar
每日一练社区 已提交
240 241 242 243 244 245 246 247 248 249
#define mem(a, b) memset(a, b, sizeof(a))
#define ll long long
const double eps = 3e-8;
const int mod = 10;
const int maxn = 10005;
vector<int> ed[maxn];
ll edge[maxn][maxn];
ll dis[maxn];
ll sum = 0;

每日一练社区's avatar
每日一练社区 已提交
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
int bfs(int node)
{
    mem(dis, -1);
    queue<int> que;
    que.push(node);
    int ans = node;
    dis[node] = 0;
    while (!que.empty())
    {
        int now = que.front();
        que.pop();
        for (int i = 0; i < ed[now].size(); i++)
        {
            int temp = ed[now][i];
            if (dis[temp] < 0)
            {
                dis[temp] = dis[now] + edge[now][temp];
每日一练社区's avatar
每日一练社区 已提交
267
                if (dis[temp] > sum)
每日一练社区's avatar
每日一练社区 已提交
268 269 270 271 272 273 274 275 276 277
                {
                    ans = temp;
                    sum = dis[temp];
                }
                que.push(temp);
            }
        }
    }
    return ans;
}
每日一练社区's avatar
每日一练社区 已提交
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301

int main()
{
    int n, a, b;
    ll c;
    scanf("%d", &n);
    for (int i = 1; i < n; i++)
    {
        scanf("%d%d%lld", &a, &b, &c);
        ed[a].push_back(b);
        ed[b].push_back(a);
        edge[a][b] = c;
        edge[b][a] = c;
    }
    int starta = 1;
    int endnode, startnode;
    sum = 0;
    endnode = bfs(starta);
    sum = 0;
    startnode = bfs(endnode);

    double ans = sum * (sum + 1.0) / 2 + 10.0 * sum;
    printf("%.0f\n", ans);
}
每日一练社区's avatar
每日一练社区 已提交
302
```