省選臨近,放飛自我的小q無心刷題,於是慫恿小c和他一起頹廢,玩起了一款戰略遊戲。
這款戰略遊戲的地圖由n個城市以及m條連線這些城市的雙向道路構成,並且從任意乙個城市出發總能沿著道路走到
任意其他城市。現在小c已經占領了其中至少兩個城市,小q可以摧毀乙個小c沒占領的城市,同時摧毀所有連線這
個城市的道路。只要在摧毀這個城市之後能夠找到某兩個小c占領的城市u和v,使得從u出發沿著道路無論如何都不
能走到v,那麼小q就能贏下這一局遊戲。
小q和小c一共進行了q局遊戲,每一局遊戲會給出小c占領的城市集合s
你需要幫小q數出有多少個城市在他摧毀之後能夠讓他贏下這一局遊戲。
首先建出圓方樹,我們發現答案就是把關鍵點連起來之後所形成的連通塊中圓點的個數減去關鍵點數量
把關鍵點建立虛樹,答案就是每一條邊的權值和,邊的權值就是省略的節點個數
按照建立虛樹的方法直接算邊權就好了
#includeusing namespace std;
templatevoid gi(t &x)
const int n=4e5+10;
int n,m,q,head[n],nxt[n*2],to[n*2],num=1,dfn[n],low[n],dfn=0,head[n];
int st[n],top=0,k,a[n],dis[n],w[n],id[n],fa[n][20],dep[n];
inline void link(int x,int y)
inline void link(int x,int y)
inline void tarjan(int x,int last)
} else low[x]=min(low[x],dfn[u]); }}
inline void dfs(int x,int last)
}inline int lca(int x,int y)
inline bool comp(const int &i,const int &j)
ans+=dis[st[top]]-dis[z],top--;
if(st[top]!=z)st[++top]=z;
st[++top]=x;
} while(top>1)ans+=dis[st[top]]-dis[st[top-1]],top--;
if(top && w[st[top]])ans++;top--;
printf("%d\n",ans-k);
}inline void clear()
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i,0);
top=dfn=0;
dfs(1,1);
cin>>q;
while(q--)solve();
}int main()
bzoj 5329 Sdoi2018 戰略遊戲
n個點m條邊,每次給出乙個點集,可以刪掉乙個非點集中的點,問有多少刪法使得存在兩個點集中的點不連通。建出圓方樹的虛樹,顯然刪去上面的圓點是合法的。直接搞就好了。code include include include include include include using namespace s...
BZOJ5329 SDOI2018 戰略遊戲
補的第一道sdoi2018?圓方樹上建虛樹 歡樂多又多 大霧 大概就是求對於s個點 問刪掉乙個點使它們不完全連通的方案數 那麼我們可以看出 這個其實就是求兩兩路徑並上的割點數量 那麼 圓方樹來解決是最好的辦法 好像也沒有別的辦法 然後我們發現如果兩兩統計lca的話,複雜度是s 2無法接受 可以看出 ...
bzoj5329 圓方樹 虛樹 戰略遊戲
description 省選臨近,放飛自我的小q無心刷題,於是慫恿小c和他一起頹廢,玩起了一款戰略遊戲。這款戰略遊戲的地圖由n個城市以及m條連線這些城市的雙向道路構成,並且從任意乙個城市出發總能沿著道路走到 任意其他城市。現在小c已經占領了其中至少兩個城市,小q可以摧毀乙個小c沒占領的城市,同時摧毀...