列表

详情


NC20210. [JSOI2015]SALESMAN

描述

某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇之间都只有唯一的可能经过其它城镇的路线。 小T可以准确地估计出在每个城镇停留的净收益。这些净收益可能是负数,即推销商品的利润抵不上花费。
由于交通不便,小T经过每个 城镇都需要停留,在每个城镇的停留次数与在该地的净收益无关,因为很多费用不是计次收 取的,而每个城镇对小T的商品需求也是相对固定的,停留一次后就饱和了。每个城镇为了 强化治安,对外地人的最多停留次数有严格的规定。
请你帮小T设计一个收益最大的巡回方案,即从家乡出发,在经过的每个城镇停留,最后回到家乡的旅行方案。你的程序只需输出最大收益,以及最优方案是否唯一。方案并不包括路线的细节,方案相同的标准是选择经过 并停留的城镇是否相同。因为取消巡回也是一种方案,因此最大收益不会是负数。小T在家乡净收益是零,因为在家乡是本地人,家乡对小T当然没有停留次数的限制。

输入描述

输入的第一行是一个正整数n(5 ≤ n ≤ 100000),表示城镇数目。城镇以1到n的数命名。小T的家乡命名为1。
第二行和第三行都包含以空格隔开的n-1个整数,第二行的第i个数表示在城镇 i+1停留的净收益。
第三行的第i个数表示城镇i+1规定的最大停留次数。
所有的最大停留次数都不小于2。接下来的n-1行每行两个1到n的正整数x,y,之间以一个空格 隔开,表示x,y之间有一条不经过其它城镇的双向道路。
输入数据保证所有城镇是连通的。

输出描述

输出有两行,第一行包含一个自然数,表示巡回旅行的最大收益。
如果该方案唯一,在 第二行输出“solution is unique”,否则在第二行输出“solution is not unique”。

示例1

输入:

9
-3 -4 2 4 -2 3 4 6
4 4 2 2 2 2 2 2 
1 2
1 3
1 4
2 5
2 6
3 7
4 8 
4 9

输出:

9
solution is unique

说明:

最佳路线包括城镇 1,2, 4, 5, 9。

原站题解

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

C++11(clang++ 3.9) 解法, 执行用时: 64ms, 内存消耗: 3684K, 提交时间: 2019-03-16 12:45:13

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=100005;

int cnt,n,val[N],lim[N],last[N],a[N],a1,f[N],g[N];
struct edge{int to,next;}e[N*2];

void addedge(int u,int v)
{
    e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;
    e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;
}

bool cmp(int a,int b)
{
    return f[a]>f[b];
}

void dfs(int x,int fa)
{
    f[x]=val[x];
    for (int i=last[x];i;i=e[i].next)
        if (e[i].to!=fa) dfs(e[i].to,x);
    a1=0;
    for (int i=last[x];i;i=e[i].next) 
        if (e[i].to!=fa) a[++a1]=e[i].to;
    sort(a+1,a+a1+1,cmp);
    int p=0;
    while (p<min(lim[x]-1,a1)&&f[a[p+1]]>=0) p++,f[x]+=f[a[p]],g[x]|=g[a[p]];
    if (p<a1&&p>0&&f[a[p]]==f[a[p+1]]||f[a[p]]==0&&p>0) g[x]=1;
}


int main()
{
    scanf("%d",&n);
    for (int i=2;i<=n;i++) scanf("%d",&val[i]);
    for (int i=2;i<=n;i++) scanf("%d",&lim[i]);
    for (int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        addedge(x,y);
    }
    lim[1]=n+1;
    dfs(1,0);
    printf("%d\n",f[1]);
    if (g[1]) printf("solution is not unique");
    else printf("solution is unique");
    return 0;
}

上一题