Wannafly挑战赛2【solved : 2 / 5】

来源:互联网 发布:网络名誉侵权证据 编辑:程序博客网 时间:2024/04/27 18:42

A Cut(贪心哈夫曼)

给你一个长度为n的序列,你每次可以将一个序列分割成两个连续的的子序列,
分割的代价为原序列的总和。
现在允许你在初始时将序列重新排列一次。
问分割成n个长度为1的序列的最大总代价是多少?

#include <bits/stdc++.h>using namespace std;int main(){    int n;    scanf("%d", &n);    vector<int>vec;    vec.resize(n);    for(int i = 0; i < n; i++)   scanf("%d", &vec[i]);    sort(vec.begin(), vec.end());    long long ans = 0;    for(int i = 0; i < n; i++)    {        if(i + 1 == n)  ans += 1LL * (n - 1) * vec[i];        else    ans += 1LL * (i + 1) * vec[i];    }    printf("%lld\n", ans);    return 0;}

B Travel(最短路)

N座城市环形排列。其中第i座城市到第i+1座城市花费的时间为d[i]。特别地,第N座城市到第1座城市花费的时间为d[N]。这些道路都是双向的。M座传送门,第i座传送门连接了城市u[i]与城市v[i],并且需要花费w[i]的时间通过(可能有两座传送门连接了同一对城市,也有可能一座传送门连接了相同的两座城市)。这些传送门都是双向的。给出Q次查询,每次查询两点之间最短距离。1NQ525011M201d[i]w[i]230

思路:考虑到M这么少,那么我们可以把查询中u到v的最短路转换成,u到x的最短路,x到v的最短路,类floyd的感觉。我们进行2*M次最短路,每次更新属于传送门的某个端点为起点的最短距离,dp[i][j]:表明传送门端点i到城市J的最短距离,答案就是min{dp[i][u]dp[i][v]}1iN

#include <bits/stdc++.h>using namespace std;const int maxn = 52501 + 5;const long long INF = 1e17;typedef pair<int, int>pii;vector<pii>G[maxn];vector<int>point;int n, m;int inq[maxn];long long sum[maxn], dist[50][maxn];void spfa(int sx){    for(int i = 1; i <= n; i++)  inq[i] = 0, dist[sx][i] = INF;    queue<int>que;    int val = point[sx];    que.push(val);    inq[val] = 1, dist[sx][val] = 0;    while(que.size())    {        int cur = que.front();que.pop();        inq[cur] = 0;        for(auto o : G[cur])        {            int to = o.first, cost = o.second;            if(dist[sx][to] > dist[sx][cur] + cost)            {                dist[sx][to] = dist[sx][cur] + cost;                if(inq[to] == 0)    que.push(to), inq[to] = 1;            }        }    }}int main(){    scanf("%d%d", &n, &m);    for(int i = 1; i <= n; i++)    {        int x;        scanf("%d", &x);        G[i].push_back({i % n + 1, x});        G[i % n + 1].push_back({i, x});        sum[i] = sum[i - 1] + x;    }    for(int i = 0; i < m; i++)    {        int x, y, w;        scanf("%d%d%d", &x, &y, &w);        G[x].push_back({y, w});        G[y].push_back({x, w});        point.push_back(x);        point.push_back(y);    }    sort(point.begin(), point.end());    point.resize(unique(point.begin(),point.end()) - point.begin());    for(int i = 0; i < point.size(); i++)    spfa(i);    int q;    scanf("%d", &q);    for(int i = 0; i < q; i++)    {        int x, y;        scanf("%d%d", &x, &y);        long long temp = abs(sum[x - 1] - sum[y - 1]);        long long ans = min(temp, sum[n] - temp);        for(int i = 0; i < point.size(); i++)        {            ans = min(ans, dist[i][x] + dist[i][y]);        }        printf("%lld\n", ans);    }    return 0;}
原创粉丝点击