hdu 4694 支配树

支配树裸题:求支配集

不太会写带权并查集,调了好久

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 #define maxn 100020
  8 #define inf 0x3f3f3f3f
  9 
 10 typedef long long ll;
 11 struct node{
 12     int next,to;
 13     void cl(){
 14         next = 0 , to = 0;
 15     }
 16 }e[maxn * 2],e2[maxn * 2];
 17 int head[maxn],head2[maxn],cnt;
 18 int n,m,fa[maxn],val[maxn],vis[maxn];
 19 int idom[maxn],semi[maxn],pnt[maxn],dfn[maxn],id[maxn],dfstime;
 20 ll ans[maxn];
 21 vector <int> ques[maxn];
 22 
 23 inline void clear(){
 24     for (int i = 1 ; i <= cnt ; i++) e[i].cl();
 25     for (int i = 1 ; i <= n ; i++) head[i] = 0;
 26     cnt = 0;
 27     for (int i = 1 ; i <= n ; i++) ques[i].clear();
 28     for (int i = 1 ; i <= n ; i++) ans[i] = 0 , id[i] = pnt[i] = fa[i] = idom[i] = semi[i] = val[i] = vis[i] = 0 , dfn[i] = inf;
 29     dfstime = 0;
 30 }
 31 inline void adde(int x,int y){
 32     e[++cnt].to = y;
 33     e2[cnt].to = x;
 34     e[cnt].next = head[x];
 35     e2[cnt].next = head2[y];
 36     head[x] = cnt;
 37     head2[y] = cnt;
 38 }
 39 inline void adde2(int x,int y){
 40     e[++cnt].to = y;
 41     e[cnt].next = head[x];
 42     head[x] = cnt;    
 43 }
 44 void dfs(int x){
 45     vis[x] = 1, dfn[x] = ++dfstime, id[dfstime] = x;
 46     for (int i = head[x] ; i ; i = e[i].next){
 47         if ( !vis[e[i].to] ) pnt[e[i].to] = x , dfs(e[i].to);
 48     }
 49 }
 50 int getfa(int x){
 51     if ( fa[x] == x ) return x;
 52     int a = getfa(fa[x]);
 53     if ( semi[val[x]] > semi[val[fa[x]]] ) val[x] = val[fa[x]];
 54     return fa[x] = a;
 55 }
 56 inline void merge(int x,int y){
 57     if ( getfa(x) != getfa(y) ) fa[y] = x;
 58 }
 59 void dfs(int x,int fa,ll cur){
 60     cur += (ll)x;
 61     ans[x] = cur;
 62     for (int i = head[x] ; i ; i = e[i].next){
 63         if ( e[i].to == fa ) continue;
 64         dfs(e[i].to,x,cur);
 65     }
 66 }
 67 void calc(){
 68     for (int i = 1 ; i <= cnt ; i++) e[i].cl(), e2[i].cl();
 69     for (int i = 1 ; i <= n ; i++) head[i] = head2[i] = 0;
 70     cnt = 0;
 71     for (int i = 1 ; i <= n ; i++){
 72         if ( idom[i] && idom[i] != i ) adde2(idom[i],i) , adde2(i,idom[i]);
 73     }
 74     dfs(n,0,0);
 75 }
 76 void solve(){
 77     semi[0] = inf;
 78     //val[x]表示到x的祖先中semi最小的点的编号
 79     //semi[x]表示x的半支配点的dfn
 80     for (int i = 1 ; i <= n ; i++) fa[i] = i , semi[i] = inf;
 81     for (int i = dfstime ; i ; i--){
 82         int x = id[i];
 83         for (int j = 0 ; j < ques[x].size() ; j++){
 84             int y = ques[x][j];
 85             getfa(y);
 86             if ( semi[val[y]] < dfn[x] ) idom[y] = val[y];
 87         }
 88         for (int j = head2[x] ; j ; j = e2[j].next){
 89             if ( dfn[x] > dfn[e2[j].to] ) semi[x] = min(semi[x],dfn[e2[j].to]); 
 90             else{
 91                 getfa(e2[j].to);  
 92                 semi[x] = min(semi[x],semi[val[e2[j].to]]);
 93             }
 94         }
 95         if ( pnt[x] ) semi[x] = min(semi[x],dfn[pnt[x]]);
 96         if ( x == n ) semi[x] = 1;
 97         if ( semi[x] < semi[val[x]] ) val[x] = x; 
 98         for (int j = head[x] ; j ; j = e[j].next)
 99             if ( pnt[e[j].to] == x ) merge(x,e[j].to);
100         ques[id[semi[x]]].push_back(x);
101     }
102     for (int i = 1 ; i <= dfstime ; i++){
103         int x = id[i];
104         if ( idom[x] ) idom[x] = idom[idom[x]]; //idom[x]最初存的是x到其semi路径上的semi最小值的点
105         else idom[x] = id[semi[x]];
106     }
107 //    for (int i = 1 ; i <= n ; i++) cout<<idom[i]<<" ";
108 //    cout<<endl;
109     calc();
110     for (int i = 1 ; i <= n ; i++){
111            printf("%lld",ans[i]);
112         if ( i < n ) printf(" ");
113     }
114     printf("
");
115 }
116 int main(){
117     freopen("input.txt","r",stdin);
118     while ( ~scanf("%d %d",&n,&m) ){
119         clear();
120         for (int i = 1 ; i <= m ; i++){
121             int x,y;
122             scanf("%d %d",&x,&y);
123             adde(x,y);
124         }
125         dfs(n);
126         solve();
127     }
128 }
原文地址:https://www.cnblogs.com/zqq123/p/5468528.html