HDU 4694: Important Sisters(支配树)

来源:互联网 发布:画婚车路线图的软件 编辑:程序博客网 时间:2024/05/17 08:34




题意:

御坂和她的n-1个克隆姐姐(编号1~n-1)构成一张御坂网络,如果第x号"姐姐"和第y号"姐姐"有条x到y的有向边,则说明x可以将信息传给y,已知御坂妹妹作为n号点,是所有信息的源头,如果屏蔽掉x点之后y点无法得到御坂妹妹的信息,那么说明x是y的支配点,对于所有的点,求出它所有支配点的编号和(包括她自身的编号)

特殊的:如果x点本身就得不到信息,该点输出0


支配树模板题

Lengauer-Tarjan算法搞定

注意不用新建节点,直接将n作为支配树的根,对于在支配树中的点,答案就是该点到根的编号和,

对于不在支配树中的点,答案为0


模板:

#pragma comment(linker, "/STACK:102400000,102400000")#include<stdio.h>#include<vector>#include<algorithm>using namespace std;#define LL long longLL n, cnt, sdom[60005], idom[60005], key[60005], rak[60005];LL dfn[60005], ufs[60005], fa[60005], val[60005];vector<LL> G[60005], Gp[60005], Z[60005], Sp[60005];LL Find(LL p){LL temp;if(ufs[p]==p)return p;temp = Find(ufs[p]);if(sdom[key[ufs[p]]]<sdom[key[p]])key[p] = key[ufs[p]];return ufs[p] = temp;}void Sech2(LL u){LL i, v;val[u] += u;for(i=0;i<Z[u].size();i++){v = Z[u][i];val[v] += val[u];Sech2(v);}}void Sech(LL p){LL i, v;dfn[p] = sdom[p] = ++cnt;rak[cnt] = p;for(i=0;i<G[p].size();i++){v = G[p][i];if(dfn[v]==0){Sech(v);fa[v] = p;}}}int main(void){LL m, i, x, y, p, j, v;while(scanf("%lld%lld", &n, &m)!=EOF){cnt = 0;for(i=1;i<=n;i++){dfn[i] = val[i] = idom[i] = sdom[i] = 0;ufs[i] = key[i] = i;G[i].clear();Gp[i].clear();Z[i].clear();}for(i=1;i<=m;i++){scanf("%lld%lld", &x, &y);G[x].push_back(y);Gp[y].push_back(x);}Sech(n);for(i=cnt;i>=2;i--){p = rak[i];for(j=0;j<Gp[p].size();j++){v = Gp[p][j];if(dfn[v]){Find(v);sdom[p] = min(sdom[p], sdom[key[v]]);}}ufs[p] = fa[p];Sp[rak[sdom[p]]].push_back(p);for(j=0;j<Sp[fa[p]].size();j++){v = Sp[fa[p]][j];Find(v);if(sdom[key[v]]==sdom[v])idom[v] = fa[p];elseidom[v] = key[v];}Sp[fa[p]].clear();}for(i=1;i<=cnt;i++){p = rak[i];if(idom[p]!=rak[sdom[p]])idom[p] = idom[idom[p]];}for(i=1;i<=n-1;i++)Z[idom[i]].push_back(i);Sech2(n);printf("%lld", val[1]);for(i=2;i<=n;i++)printf(" %lld", val[i]);printf("\n");}return 0;}/*13 21 13 2   11 12   7 4 2 3   12 1   6 4 3 4   13 11 4 5   8 12 2 6   1 10 6 7   10 9 13 8   10 5 8 9   5 13 9 10  5 4 8 11 */


原创粉丝点击