列表

详情


NC24595. [USACO 2011 Ope G]Soldering

描述

The cows are playing with wires! They have learned a technique called soldering, in which they connect two pieces of wire together by attaching the endpoint of one wire to a location along the length of the other. (Soldering endpoint to endpoint is not allowed.) There can be multiple solder junctions at the same point.
The cows have a plan for an Amazing Structure they would like to build. It is in the form of a graph with N (1 <= N <= 50,000) nodes and N-1 edges of unit length so that each pair of nodes is connected. Each edge is described by a pair of integers, A and B (1 <= A <= N; 1 <= B <= N; A != B).
The cows are able to buy wire from a local store; however longer wire is more expensive. In particular the cows can buy a wire of length L with cost L*L, but they cannot cut wires or join wires together.
Given the plan, the cows would like solder wires together to build their Amazing Structure. Please help them find the minimum possible cost!
Test data worth at least 50% of the points will have N <= 2,000.
Partial feedback will be provided on your first 50 submissions to this problem.

输入描述

* Line 1: A single integer: N
* Lines 2..N: Two space-separated integers describing an edge: A and B

输出描述

* Line 1: A single integer, the cost of soldering the tree together. Note that this number may not always fit in a 32-bit integer.

示例1

输入:

6 
1 2 
1 3 
1 4 
1 5 
1 6

输出:

7

说明:

Since all nodes in the structure are connected to node 1, we only need to buy one wire of length 2 and three of length 1, for a total cost of 2 * 2 + 1 * 1 + 1 * 1 + 1 * 1 = 7.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 57ms, 内存消耗: 10212K, 提交时间: 2020-03-14 11:57:58

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<vector>
#define ll long long
using namespace std;
const int N=50001;
struct st
{
    int l; ll co;
    st(){}
    st(int x,ll y){l=x; co=y;}
    ll cal(){return co+l*l;}
    bool operator <(const st x) const{return l<x.l || (l==x.l && co<x.co);}
};
vector <st> f[N],g;
vector <int> l[N];
int n,i,x,y;
bool vis[N];
void dp(int x,int d)
{
    vis[x]=1;
    f[d].clear();
    bool leaf=1;
    int m1=l[x].size(),m2,m3;
    for (int k=0;k<m1;k++)
        if (!vis[l[x][k]])
        {
            leaf=0;
            dp(l[x][k],d+1);
            m3=f[d+1].size();
            for (int i=0;i<m3;i++) f[d+1][i].l++;
            if (!f[d].size()){f[d]=f[d+1]; continue;}
            g.clear();
            m2=f[d].size();
            for (int i=0;i<m2;i++)
                for (int j=0;j<m3;j++)
                    if (!f[d][i].l) g.push_back(st(0,f[d][i].co+f[d+1][j].cal()));
                    else
                    {
                        g.push_back(st(f[d][i].l,f[d][i].co+f[d+1][j].cal()));
                        g.push_back(st(f[d+1][j].l,f[d+1][j].co+f[d][i].cal()));
                        g.push_back(st(0,f[d][i].cal()+f[d+1][j].cal()+((f[d][i].l*f[d+1][j].l)<<1)));
                    }
            sort(g.begin(),g.end());
            int num=0;
            m2=g.size();
            for (int i=1;i<m2;i++)
                if (g[i].cal()<g[num].cal()) g[++num]=g[i];
            g.resize(num+1);
            f[d]=g;
        }
    if (leaf) f[d].push_back(st(0,0));
}
int main()
{
        scanf("%d\n",&n);
        for (i=1;i<n;i++)
        {
            scanf("%d%d\n",&x,&y);
            l[x].push_back(y);
            l[y].push_back(x);
        }
        dp(1,0);
        printf("%lld",f[0][0].cal());
}

上一题