【題解】 bzoj4472: [Jsoi2015]salesman (動態規劃)
阿新 • • 發佈:2018-04-29
規劃 problem 越界 PE names 子節點 tin www. uniq
bzoj4472,懶得復制,戳我戳我
Solution:
體面意思:從\(1\)號節點出發,每到一個節點就必須停下,獲得節點權值(每個節點只會獲得一次),每個點有個規定的停留次數,求最大可獲得多大權值,並且判斷是否只有唯一的路線才能獲得這個權值
- 直接\(dp\)儲存子樹最大獲得權值就行,順便要記錄方案是否唯一,所以我們可以拿一個結構體來記錄
- \(dp\)權值思路:找出所有子樹中前\(vis[i]-1\)大的節點權值(只選大於\(0\)的權值)。
- \(dp\)方案思路: 1.如果有選擇的節點是方案不唯一的,該子樹根節點也是方案不唯一。 2. 如果有子節點權值為\(0\),該子樹根節點方案不唯一。 3.
Attention:
- 記錄子樹的結構體時用\(vector\)更好,不然容易超時越界一堆問題
(不會用\(vector\)強行卡代碼時間卡過去了)
Code:
//It is coded by Ning_Mew on 4.22
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<‘0‘||ch>‘9‘ ){if(ch==‘-‘)f=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
return x*f;
}
int n,val[maxn],fa[maxn],vis[maxn];
struct Node{
int val;bool uni;
Node(){val=0;uni=false;}
}node[maxn];
int head[maxn],cnt=0;
struct Edge{int nxt,to;}edge[maxn*2];
void add(int from,int to){
edge[++cnt].nxt=head[from];
edge[cnt].to=to;
head[from]=cnt;
}
bool cmp(const Node &x,const Node &y){return x.val>y.val;}
void dfs(int u){
bool son=false;
Node box[maxn/128];int ct=0;
for(int i=head[u];i!=0;i=edge[i].nxt){
int v=edge[i].to;if(v==fa[u])continue;
fa[v]=u;son=true;
dfs(v);
ct++; box[ct]=node[v];
}
if(!son){node[u].val=val[u]; node[u].uni=false;return;}
sort(box+1,box+ct+1,cmp);
for(int i=1;i<=min(vis[u]-1,ct);i++){
if(box[i].val>=0){
node[u].val+=box[i].val;
if(box[i].uni)node[u].uni=true;
if(box[i].val==0){node[u].uni=true;break;}
}else break;
}
node[u].val+=val[u];
if(vis[u]-1<ct&&box[ vis[u] ].val==box[ vis[u]-1 ].val&&box[ vis[u] ].val>=0)node[u].uni=true;
return;
}
int main(){
//freopen("in.in","r",stdin);
memset(head,0,sizeof(head));cnt=0;
scanf("%d",&n);
vis[1]=maxn;
for(int i=2;i<=n;i++)/*val[i]=read();*/scanf("%d",&val[i]);
for(int i=2;i<=n;i++)/*vis[i]=read();*/scanf("%d",&vis[i]);
for(int i=1;i<=n-1;i++){
int u,v;/*u=read();v=read();*/scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs(1);
printf("%d\n",node[1].val);
if(!node[1].uni)printf("solution is unique\n");
else printf("solution is not unique\n");
return 0;
}
【題解】 bzoj4472: [Jsoi2015]salesman (動態規劃)