题意:
就是给你一个树,然后让你给每个点一个权值。要保证,对于删掉任意一个点,剩下的所有自联通块的权值和都必须一样。
思考:
对于删掉一个点,子树权值还一样。刚开始我以为删掉一个点后就剩两个子树,实际上可以剩很多子树,看这个点的度为多少,子树就有多少。然后到底该怎么办呢,感觉和度数有关,要不然凭空构造一个树那么复杂肯定很难构造。其实就是从任意一点开始搜,每个点的权值就是度数,有的为负有的为正,对图进行二染色,一种颜色都是正的,一种颜色都是负的。这样整个图下来,每个度会有两个点,每个点一正一负正好权值和为0。所以这样就是正确的,感性的思考一下,感觉这样也是可以的。
代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define db double
#define int long long
#define PII pair<int,int >
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const int mod = 1e9+7,inf = 1e18;
const int N = 2e5+10,M = 2010;
int T,n,m,k;
int va[N];
int anw[N],in[N];
vector<int > e[N];
void dfs(int now,int p,int c)
{
anw[now] = in[now]*c;
for(auto spot:e[now])
{
if(spot==p) continue;
dfs(spot,now,-c);
}
}
signed main()
{
IOS;
cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
e[i].clear();
anw[i] = in[i] = 0;
}
for(int i=1;i<n;i++)
{
int a,b;
cin>>a>>b;
e[a].pb(b);
e[b].pb(a);
in[a]++,in[b]++;
}
dfs(1,0,-1);
for(int i=1;i<=n;i++) cout<<anw[i]<<" ";
cout<<"\n";
}
return 0;
}
总结:
多多思考,多多猜想。