在建边的时候,如果建单向边就会全 wa,改成双向边就 ac 了,在 dp 的时候是把子节点的信息传给父亲,所以单向边应该也可以,但是为什么会 wa 呢?
这是 ac 代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
int f=1;
int res=0;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
res=res*10+ch-'0';
ch=getchar();
}
return res*f;
}
const int maxn=1e5+5;
int n;
int val[maxn],tot[maxn];
int u,v;
vector<int> edge[maxn];
int dp[maxn];
bool flag;
bool cmp(int a,int b){
return dp[a]>dp[b];
}
void dfs(int now,int fa){
for(int i=0;i<edge[now].size();i++){
int v=edge[now][i];
if(v==fa)
continue;
dfs(v,now);
}
int tmp=dp[now];
int sum=0;
sort(edge[now].begin(),edge[now].end(),cmp);
for(int i=0;i<edge[now].size();i++){
int v=edge[now][i];
if(v==fa)
continue;
sum++;
if(dp[v]==0 || (tot[now]==sum && dp[v]==dp[edge[now][i-1]]))
flag=true;
if(dp[v]<0 || sum>tot[now])
break;
dp[now]+=dp[v];
}
}
signed main(){
n=read();
val[1]=0;
tot[1]=0x3f3f3f3f;
for(int i=2;i<=n;i++){
val[i]=read();
}
for(int i=2;i<=n;i++){
tot[i]=read();
tot[i]--;
}
for(int i=1;i<=n-1;i++){
u=read(),v=read();
edge[u].push_back(v);
edge[v].push_back(u);
}
for(int i=1;i<=n;i++)
dp[i]=val[i];
dfs(1,0);
printf("%lld\n",dp[1]);
if(flag)
printf("solution is not unique\n");
else
printf("solution is unique\n");
return 0;
}
这是全 wa 代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int read(){
int f=1;
int res=0;
char ch=getchar();
while(ch<'0' || ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9'){
res=res*10+ch-'0';
ch=getchar();
}
return res*f;
}
const int maxn=1e5+5;
int n;
int val[maxn],tot[maxn];
int u,v;
vector<int> edge[maxn];
int dp[maxn];
bool flag;
bool cmp(int a,int b){
return dp[a]>dp[b];
}
void dfs(int now,int fa){
for(int i=0;i<edge[now].size();i++){
int v=edge[now][i];
if(v==fa)
continue;
dfs(v,now);
}
int tmp=dp[now];
int sum=0;
sort(edge[now].begin(),edge[now].end(),cmp);
for(int i=0;i<edge[now].size();i++){
int v=edge[now][i];
if(v==fa)
continue;
sum++;
if(dp[v]==0 || (tot[now]==sum && dp[v]==dp[edge[now][i-1]]))
flag=true;
if(dp[v]<0 || sum>tot[now])
break;
dp[now]+=dp[v];
}
}
signed main(){
n=read();
val[1]=0;
tot[1]=0x3f3f3f3f;
for(int i=2;i<=n;i++){
val[i]=read();
}
for(int i=2;i<=n;i++){
tot[i]=read();
tot[i]--;
}
for(int i=1;i<=n-1;i++){
u=read(),v=read();
edge[u].push_back(v);
//edge[v].push_back(u);
}
for(int i=1;i<=n;i++)
dp[i]=val[i];
dfs(1,0);
printf("%lld\n",dp[1]);
if(flag)
printf("solution is not unique\n");
else
printf("solution is unique\n");
return 0;
}