题解
此题与USACO Max Flow几乎是一样的(代码也几乎一样)。细节就自己想吧。
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int toq[600100],nxtq[600100],headq[300100],totq;
int top[600100],nxtp[600100],headp[300100],totp;
int tmpfa[300100],fa[300100],record[300100],map[300100];
bool vis[300100];
void addq(int f,int t)
{
toq[++totq] = t;
nxtq[totq] = headq[f];
headq[f] = totq;
}
void addp(int f,int t)
{
top[++totp] = t;
nxtp[totp] = headp[f];
headp[f] = totp;
}
int find(int x){
if(tmpfa[x] == x)return x;
return tmpfa[x] = find(tmpfa[x]);
}
void tarjan(int pos,int pre)
{
tmpfa[pos] = pos;
for(int i = headp[pos];i;i = nxtp[i])
if(top[i] != pre){
tarjan(top[i],pos);
tmpfa[top[i]] = pos;
}
vis[pos] = true;
for(int i = headq[pos];i;i = nxtq[i])
if(vis[toq[i]]){
int tmp_lca = find(toq[i]);
record[tmp_lca]--,record[fa[tmp_lca]]--,record[pos]++,record[toq[i]]++;
}
}
void dfs(int pos,int pre)
{
fa[pos] = pre;
for(int i = headp[pos];i;i = nxtp[i])
if(top[i] != pre)
dfs(top[i],pos);
}
void dfsans(int pos,int pre)
{
for(int i = headp[pos];i;i = nxtp[i])
if(top[i] != pre){
dfsans(top[i],pos);
record[pos] += record[top[i]];
}
}
int main()
{
scanf("%d",&n);
int f,t,ori;
scanf("%d",&f);ori = f;
for(int i = 1;i < n;i++){
scanf("%d",&t);
map[t] = -1;
addq(f,t),addq(t,f);
f = t;
}
for(int i = 1;i < n;i++){
scanf("%d%d",&f,&t);
addp(f,t),addp(t,f);
}
dfs(1,0);
tarjan(1,0);
dfsans(1,0);
for(int i = 1;i <= n;i++){
if(i == ori)
printf("%d\n",record[i]);
else
printf("%d\n",record[i] - 1);
}
}