ACdream 1015Double Kings

来源:互联网 发布:拍小视频创意点子 知乎 编辑:程序博客网 时间:2024/06/03 13:54

http://acdream.info/problem?pid=1015



关于图的博弈,a和b在一个生成树中选2个节点,距离较近的点则为各自拥有,如果离2人距离相等则属于a,a先选,求a能获得的最多点数。
思路就是a选了一个点,把这个点当成一个根节点来看,那么b只能在a的子树中来选,为了能获得更多,一定会选择a的子树中最多节点数的子树的根节点。那么为了使a得到最大,求每个点作为根节点时,其节点最多子树的最小值即可。





#include<bits/stdc++.h>using namespace std;struct node{int a;int nex;int b;};int n;node e[111111];int ans[55555];int fa[55555];int js;void add(int x, int y) {        js++;    e[js].a=y;e[js].b=0;    e[js].nex=fa[x];    fa[x]=js;}void dfs(int x,int y){for(int i=fa[x];i!=-1;i=e[i].nex){if(e[i].a!=y){dfs(e[i].a,x);for(int j=fa[e[i].a];j!=-1;j=e[j].nex){if(e[j].a==x)continue;e[i].b+=e[j].b;}e[i].b+=1;            e[i^1].b=n-e[i].b;}}}int main(){while(cin>>n){js=-1;memset(ans,0,sizeof(ans));memset(fa,0xff,sizeof(fa));int x,y;for(int i=1;i<n;i++){cin>>x>>y;add(x,y);add(y,x);}dfs(1,0);int ans1=0x7ffffff;for(int i=1;i<=n;i++){            for(int j=fa[i];j!=-1;j=e[j].nex){                ans[i]=max(ans[i],e[j].b);            }            ans1=min(ans1,ans[i]);        }        cout<<n-ans1<<endl;}return 0;}