# Xor-MST Codeforces - 888G

https://codeforces.com/contest/888/problem/G

Cut property

For any cut C of the graph, if the weight of an edge e in the cut-set of C is strictly smaller than the weights of all other edges of the cut-set of C, then this edge belongs to all MSTs of the graph.

Proof: Assume that there is an MST T that does not contain e. Adding e to T will produce a cycle, that crosses the cut once at e and crosses back at another edge e' . Deleting e' we get a spanning tree T∖{e'}∪{e} of strictly smaller weight than T. This contradicts the assumption that T was a MST.

By a similar argument, if more than one edge is of minimum weight across a cut, then each such edge is contained in some minimum spanning tree.

This figure shows the cut property of MSTs. T is the only MST of the given graph. If S = {A,B,D,E}, thus V-S = {C,F}, then there are 3 possibilities of the edge across the cut(S,V-S), they are edges BC, EC, EF of the original graph. Then, e is one of the minimum-weight-edge for the cut, therefore S ∪ {e} is part of the MST T.

1.(d?(1<<i):0),(d<<i),d*(1<<i)中，最后一个最快？

2.结构体里面删掉一些东西会快？

  1 #pragma GCC optimize("Ofast")
2 #include<cstdio>
3 #include<algorithm>
4 #include<cstring>
5 #include<vector>
6 #include<cassert>
7 using namespace std;
8 #define fi first
9 #define se second
10 #define mp make_pair
11 #define pb push_back
12 typedef long long ll;
13 typedef unsigned long long ull;
14 struct pii
15 {
16     int fi,se;
17     pii():fi(0),se(0){}
18     pii(int a,int b):fi(a),se(b){}
19 };
20 struct P
21 {
22     int a,b,c;
23 };
24 namespace S
25 {
26
27 const int N=7000000;
28 struct N
29 {
30     int ch[2],fi,se;//,sz
31 }dd[N];
32 int mem;
33 int rt;
34 int gnode()
35 {
36     int t=++mem;dd[t].ch[0]=dd[t].ch[1]=0;//dd[t].sz=0;
37     dd[t].fi=dd[t].se=0;
38     return t;
39 }
40 const int dep=30;
41 #define num rt
42 void insert(int x,int y)
43 {
44     //if(!num)    num=gnode();
45     //++dd[num].sz;
46     int d;int i,p=num;
47     /*
48     if(!(dd[p].fi==y||dd[p].se==y))
49     {
50         if(!dd[p].fi)    dd[p].fi=y;
51         else if(!dd[p].se)    dd[p].se=y;
52     }
53     */
54     for(i=dep;i>=0;--i)
55     {
56         d=(x>>i)&1;
57         if(!dd[p].ch[d])   dd[p].ch[d]=gnode();
58         p=dd[p].ch[d];//++dd[p].sz;
59         if(!(dd[p].fi==y||dd[p].se==y))
60         {
61             (dd[p].fi?dd[p].se:dd[p].fi)=y;
62             /*
63             if(!dd[p].fi)    dd[p].fi=y;
64             else if(!dd[p].se)    dd[p].se=y;
65             */
66         }
67     }
68 }
69 /*
70 void erase(int x)
71 {
72     --dd[num].sz;
73     bool d;int i,p=num;
74     for(i=dep;i>=0;--i)
75     {
76         d=x&(1<<i);
77         p=dd[p].ch[d];
78         assert(p);
79         --dd[p].sz;
80     }
81 }
82 */
83 //inline bool jud(int p,int y)
84 //{
85 //    return
86 #define jud(p,y)    (!dd[p].fi||(dd[p].fi==y&&!dd[p].se))
87 //}
88 pii que(int x,int y)
89 {
90     int p=num;
91     int d,d2;int i,an=0;
92     for(i=dep;i>=0;--i)
93     {
94         d=(x>>i)&1;
95         //d=(x&(1<<i));
96         d2=jud(dd[p].ch[d],y);
97         p=dd[p].ch[d^d2];
98         (an|=(d2*(1<<i)));
99     }
100     if(dd[p].fi!=y)    return pii(an,dd[p].fi);
101     else    return pii(an,dd[p].se);
102 }
103 #undef num
104
105 }
106 int n,a[200010],fa[200010];
107 //vector<int> d[200010];
108 P tmp[200010];int tlen;
109 ll ans;
110 int n1;
111 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
112 inline void merge(int x,int y,int z)
113 {
114     //printf("1t%d %d %d\n",x,y,z);
115     x=find(x);y=find(y);
116     //scanf("%d",new int);
117     if(x==y)    return;
118     fa[x]=y;ans+=z;--n1;
119 }
120 struct E
121 {
122     int to,nxt;
123 }e[200010];
124 int f1[200010],ne;
125 int main()
126 {
127     int i,k,fx;pii an,t;
128     //n=200000;
129     scanf("%d",&n);
130     for(i=1;i<=n;++i)
131     {
132         //a[i]=rand()%(1<<30);
133         scanf("%d",&a[i]);
134     }
135     for(i=1;i<=n;++i)
136         fa[i]=i;
137     n1=n;
138     //for(int ttt=1;ttt<=15;++ttt)//
139     while(n1>1)
140     {
141         //printf("1t%d\n",n1);
142         S::mem=0;S::rt=S::gnode();
143         tlen=0;
144         memset(f1+1,0,sizeof(f1[0])*n);
145         ne=0;
146         for(i=1;i<=n;++i)
147         {
148             fx=find(i);
149             S::insert(a[i],fx);
150             e[++ne].to=i;e[ne].nxt=f1[fx];f1[fx]=ne;
151             //d[find(i)].pb(i);
152         }
153         for(i=1;i<=n;++i)
154             if(find(i)==i)
155             {
156                 //for(k=f1[i];k;k=e[k].nxt)
157                 //    S::erase(a[e[k].to]);
158                 an=pii(0x3f3f3f3f,0x3f3f3f3f);
159                 for(k=f1[i];k;k=e[k].nxt)
160                 {
161                     t=S::que(a[e[k].to],i);
162                     if(t.fi<an.fi)    an=t;
163                 }
164                 //printf("at%d %d %d\n",i,an.fi,an.se);
165                 tmp[++tlen].a=i;tmp[tlen].b=an.se;tmp[tlen].c=an.fi;
166                 //merge(i,an.se,an.fi);
167                 //for(k=f1[i];k;k=e[k].nxt)
168                 //    S::insert(a[e[k].to],i);
169             }
170         for(i=1;i<=tlen;++i)
171             merge(tmp[i].a,tmp[i].b,tmp[i].c);
172         //puts("end");
173     }
174     printf("%lld",ans);
175     return 0;
176 }
View Code

posted @ 2018-10-31 10:24  hehe_54321  阅读(357)  评论(0编辑  收藏  举报