次小生成树

 

bzoj

代码好像不太对???

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <algorithm>
  5 using namespace std;
  6 const int maxn=1e5+10;
  7 const int maxm=3e5+10;
  8 const double minv=1e-8;
  9 
 10 struct node
 11 {
 12     int d,len;
 13     node *next;
 14 }*tr[maxn];
 15 
 16 struct rec
 17 {
 18     int x,y,z;
 19 }e[maxm];
 20 ///f:某个点的前2^k个点(树)
 21 int n,m,fa[maxn],f[maxn][20],v[maxn][20],q[maxn],dep[maxn],sum=0;
 22 bool vis[maxn],use[maxn];
 23 
 24 int cmp(rec a,rec b)
 25 {
 26     return a.z<b.z;
 27 }
 28 
 29 int getf(int d)
 30 {
 31     if (fa[d]==d)
 32         return d;
 33     fa[d]=getf(fa[d]);
 34     return fa[d];
 35 }
 36 
 37 void MST()
 38 {
 39     node *p;
 40     int i,j=0,k,a,b;
 41     for (i=1;i<=n;i++)
 42         fa[i]=i;
 43     sort(e+1,e+m+1,cmp);
 44     for (k=1;k<=m;k++)
 45     {
 46         a=getf(e[k].x);
 47         b=getf(e[k].y);
 48         if (a==b)
 49             continue;
 50         fa[b]=a;
 51         sum+=e[k].z;
 52         use[k]=1;
 53 
 54         a=e[k].x;
 55         b=e[k].y;
 56         p=new node();
 57         p->d=b;
 58         p->len=e[k].z;
 59         p->next=tr[a];
 60         tr[a]=p;
 61         p=new node();
 62         p->d=a;
 63         p->len=e[k].z;
 64         p->next=tr[b];
 65         tr[b]=p;
 66 
 67         j++;
 68         if (j==n-1)
 69             break;
 70     }
 71 }
 72 
 73 void SecondMST()
 74 {
 75     node *p;
 76     int i,j,k,d,dd,x,y,head,tail,len,re=1e9;
 77     q[1]=1;
 78     dep[1]=0;
 79     vis[1]=1;
 80     head=0,tail=1;
 81     while (head<tail)
 82     {
 83         head++;
 84         d=q[head];
 85         p=tr[d];
 86         while (p)
 87         {
 88             dd=p->d;
 89             if (!vis[dd])
 90             {
 91                 vis[dd]=1;
 92                 dep[dd]=dep[d]+1;
 93                 q[++tail]=dd;
 94 
 95                 j=d;
 96                 k=0;
 97                 while (j)
 98                 {
 99                     f[dd][k]=j;
100                     if (k==0)
101                         v[dd][k]=p->len;
102                     else
103                         v[dd][k]=max(v[dd][k-1],v[f[dd][k-1]][k-1]);
104                     j=f[j][k];
105                     k++;
106                 }
107             }
108             p=p->next;
109         }
110     }
111 
112     for (i=1;i<=m;i++)
113     {
114         if (use[i])
115             continue;
116         len=0;
117         x=e[i].x;
118         y=e[i].y;
119         if (dep[x]<dep[y])
120             swap(x,y);
121         j=dep[x]-dep[y];
122         k=0;
123         while (j)
124         {
125             if (j & 1)
126             {
127                 len=max(len,v[x][k]);
128                 x=f[x][k];
129             }
130             j>>=1;
131             k++;
132         }
133 
134         if (dep[x]==0)
135             k=0;
136         else
137             k=log(dep[x]+minv)/log(2)+1;
138         j=1<<k;
139         while (k--)
140         {
141             j>>=1;
142             if (dep[x]>=j && f[x][k]!=f[y][k])
143             {
144                 len=max(len,max(v[x][k],v[y][k]));
145                 x=f[x][k];
146                 y=f[y][k];
147             }
148         }
149         if (x!=y)
150         {
151             len=max(len,v[x][0]);
152             x=f[x][0];
153         }
154         re=min(re,e[i].z-len);
155     }
156     printf("%d",re+sum);
157 }
158 
159 int main()
160 {
161     int i;
162     scanf("%d%d",&n,&m);
163     for (i=1;i<=m;i++)
164         scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
165     MST();
166     SecondMST();
167     return 0;
168 }

 

严格次小生成树

https://www.luogu.org/problemnew/show/P4180

90分,而且还是第一个数据错了,非常难受!

 

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <algorithm>
  5 using namespace std;
  6 #define ll long long
  7 const int maxn=1e5+10;
  8 const int maxm=3e5+10;
  9 const double minv=1e-8;
 10 
 11 /**
 12 easily wrong point:
 13 ll,use[maxm]
 14 **/
 15 
 16 struct node
 17 {
 18     int d,len;
 19     node *next;
 20 }*tr[maxn];
 21 
 22 struct rec
 23 {
 24     int x,y,z;
 25 }e[maxm];
 26 ///f:某个点的前2^k个点(树)
 27 int n,m,fa[maxn],f[maxn][20],v[maxn][20][2],q[maxn],dep[maxn];
 28 ll sum=0;
 29 bool vis[maxn],use[maxm];
 30 
 31 int cmp(rec a,rec b)
 32 {
 33     return a.z<b.z;
 34 }
 35 
 36 int getf(int d)
 37 {
 38     if (fa[d]==d)
 39         return d;
 40     fa[d]=getf(fa[d]);
 41     return fa[d];
 42 }
 43 
 44 void MST()
 45 {
 46     node *p;
 47     int i,j=0,k,a,b;
 48     for (i=1;i<=n;i++)
 49         fa[i]=i;
 50     sort(e+1,e+m+1,cmp);
 51     for (k=1;k<=m;k++)
 52     {
 53         a=getf(e[k].x);
 54         b=getf(e[k].y);
 55         if (a==b)
 56             continue;
 57         fa[b]=a;
 58         sum+=e[k].z;
 59         use[k]=1;
 60 
 61         a=e[k].x;
 62         b=e[k].y;
 63         p=new node();
 64         p->d=b;
 65         p->len=e[k].z;
 66         p->next=tr[a];
 67         tr[a]=p;
 68         p=new node();
 69         p->d=a;
 70         p->len=e[k].z;
 71         p->next=tr[b];
 72         tr[b]=p;
 73 
 74         j++;
 75         if (j==n-1)
 76             break;
 77     }
 78 }
 79 
 80 void SecondMST()
 81 {
 82     node *p;
 83     int i,j,k,l,d,dd,x,y,head,tail,len,re=2e9;
 84     q[1]=1;
 85     dep[1]=0;
 86     vis[1]=1;
 87     head=0,tail=1;
 88     while (head<tail)
 89     {
 90         head++;
 91         d=q[head];
 92         p=tr[d];
 93         while (p)
 94         {
 95             dd=p->d;
 96             if (!vis[dd])
 97             {
 98                 vis[dd]=1;
 99                 dep[dd]=dep[d]+1;
100                 q[++tail]=dd;
101 
102                 j=d;
103                 k=0;
104                 while (j)
105                 {
106                     f[dd][k]=j;
107                     if (k==0)
108                     {
109                         v[dd][k][0]=p->len;
110                         v[dd][k][1]=-1;
111                     }
112                     else
113                     {
114                         v[dd][k][0]=v[dd][k-1][0];
115                         v[dd][k][1]=v[dd][k-1][1];
116                         for (l=0;l<2;l++)
117                             if (v[dd][k][0]<v[f[dd][k-1]][k-1][l])
118                             {
119                                 v[dd][k][1]=v[dd][k][0];
120                                 v[dd][k][0]=v[f[dd][k-1]][k-1][l];
121                             }
122                             else if (v[dd][k][1]<v[f[dd][k-1]][k-1][l] && v[dd][k][0]!=v[f[dd][k-1]][k-1][l])
123                                 v[dd][k][1]=v[f[dd][k-1]][k-1][l];
124                     }
125                     j=f[j][k];
126                     k++;
127                 }
128             }
129             p=p->next;
130         }
131     }
132 
133     for (i=1;i<=m;i++)
134     {
135         if (use[i])
136             continue;
137         len=0;
138         x=e[i].x;
139         y=e[i].y;
140         if (dep[x]<dep[y])
141             swap(x,y);
142         j=dep[x]-dep[y];
143         k=0;
144         while (j)
145         {
146             if (j & 1)
147             {
148                 for (l=0;l<2;l++)
149                     if (v[x][k][l]!=e[i].z)
150                         len=max(len,v[x][k][l]);
151                 x=f[x][k];
152             }
153             j>>=1;
154             k++;
155         }
156 
157         if (dep[x]==0)
158             k=0;
159         else
160             k=log(dep[x]+minv)/log(2)+1;
161         j=1<<k;
162         while (k--)
163         {
164             j>>=1;
165             if (dep[x]>=j && f[x][k]!=f[y][k])
166             {
167                 for (l=0;l<2;l++)
168                     if (v[x][k][l]!=e[i].z)
169                         len=max(len,v[x][k][l]);
170                 for (l=0;l<2;l++)
171                     if (v[y][k][l]!=e[i].z)
172                         len=max(len,v[y][k][l]);
173                 x=f[x][k];
174                 y=f[y][k];
175             }
176         }
177         if (x!=y)
178         {
179             for (l=0;l<2;l++)
180                 if (v[x][0][l]!=e[i].z)
181                     len=max(len,v[x][0][l]);
182             for (l=0;l<2;l++)
183                 if (v[y][0][l]!=e[i].z)
184                     len=max(len,v[y][0][l]);
185 //            x=f[x][0];
186         }
187         if (len!=0)
188             re=min(re,e[i].z-len);
189     }
190 //    ///not exists
191 //    if (re==1e9)
192     printf("%lld",re+sum);
193 }
194 
195 int main()
196 {
197     int i;
198     scanf("%d%d",&n,&m);
199     for (i=1;i<=m;i++)
200         scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
201     MST();
202     SecondMST();
203     return 0;
204 }
205 /*
206 5 5
207 1 2 1
208 2 3 2
209 3 4 2
210 4 5 2
211 5 1 2
212 
213 4 4
214 1 2 1000000000
215 2 3 1000000000
216 3 4 999999999
217 4 1 1000000000
218 */

 

posted @ 2018-12-04 18:34  congmingyige  阅读(118)  评论(0编辑  收藏  举报