次小生成树
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 */