cf827D Best Edge Weight (kruskal+倍增lca+並查集)
阿新 • • 發佈:2018-11-11
先用kruskal處理出一個最小生成樹
對於非樹邊,倍增找出兩端點間的最大邊權-1就是答案
對於樹邊,如果它能被替代,就要有一條非樹邊,兩端點在樹上的路徑覆蓋了這條樹邊,而且邊權不大於這條樹邊
這裡可以樹剖來做,但是不想用..
如果先把非樹邊從小到大排序然後去覆蓋樹邊,那麼一條樹邊只需要被覆蓋一次
所以可以用一個並查集來把父子邊被覆蓋的點合到一起,在合併之前記下來這次覆蓋的邊權,下次再覆蓋的時候直接跳過去就可以
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4using namespace std; 5 typedef long long ll; 6 const int maxn=2e5+10,inf=1e9+1; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 11 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 12 returnx*neg; 13 } 14 15 struct Edge{ 16 int a,b,l,ne; 17 bool used; 18 }eg[maxn],eg2[maxn*2]; 19 int egh[maxn],ect; 20 int N,M,fa[maxn][20],bf[maxn],bm[maxn],ma[maxn][20],dep[maxn]; 21 int ans[maxn]; 22 23 inline int getf(int x){return bf[x]==x?x:bf[x]=getf(bf[x]);} 24 inline boolcmp(Edge a,Edge b){return a.l<b.l;} 25 inline void adeg(int a,int b,int c){ 26 eg2[++ect].b=b;eg2[ect].ne=egh[a]; 27 eg2[ect].l=c,egh[a]=ect; 28 } 29 30 void dfs(int x){ 31 // printf("!!%d %d %d\n",x,fa[x][0],ma[x][0]); 32 for(int i=0;fa[x][i]&&fa[fa[x][i]];i++) 33 fa[x][i+1]=fa[fa[x][i]][i],ma[x][i+1]=max(ma[x][i],ma[fa[x][i]][i]); 34 for(int i=egh[x];i;i=eg2[i].ne){ 35 int b=eg2[i].b; 36 if(b==fa[x][0]) continue; 37 ma[b][0]=eg2[i].l; 38 fa[b][0]=x;dep[b]=dep[x]+1; 39 dfs(b); 40 } 41 } 42 43 int lca(int x,int y){ 44 if(dep[x]<dep[y]) swap(x,y); 45 int re=0; 46 for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){ 47 if(fa[x][i]&&dep[fa[x][i]]>=dep[y]) 48 re=max(re,ma[x][i]),x=fa[x][i]; 49 } 50 if(x==y) return re; 51 for(int i=log2(dep[x]);i>=0;i--){ 52 if(fa[x][i]!=fa[y][i]) 53 re=max(re,max(ma[x][i],ma[y][i])),x=fa[x][i],y=fa[y][i]; 54 } 55 return max(re,max(ma[x][0],ma[y][0])); 56 } 57 58 int main(){ 59 //freopen("","r",stdin); 60 int i,j,k; 61 N=rd(),M=rd(); 62 for(i=1;i<=M;i++){ 63 eg[i].a=rd(),eg[i].b=rd(),eg[i].l=rd(); 64 eg[i].ne=i; 65 } 66 sort(eg+1,eg+M+1,cmp); 67 for(i=1;i<=N;i++) bf[i]=i; 68 for(i=1,j=0;i<=M&&j<N-1;i++){ 69 int a=getf(eg[i].a),b=getf(eg[i].b); 70 if(a!=b){ 71 bf[a]=b; 72 adeg(eg[i].a,eg[i].b,eg[i].l); 73 adeg(eg[i].b,eg[i].a,eg[i].l); 74 eg[i].l=inf;eg[i].used=1; 75 j++; 76 } 77 } 78 dep[1]=1;dfs(1); 79 sort(eg+1,eg+M+1,cmp); 80 for(i=1;i<=N;i++) bf[i]=i,bm[i]=inf; 81 for(i=1;i<=M;i++){ 82 if(eg[i].used) continue; 83 int a=getf(eg[i].a),b=getf(eg[i].b); 84 while(a!=b){ 85 if(dep[a]<dep[b]) swap(a,b); 86 int bb=getf(fa[a][0]); 87 bf[a]=bb,bm[a]=eg[i].l; 88 a=bb; 89 } 90 } 91 for(i=1;i<=M;i++){ 92 if(eg[i].used){ 93 int a=eg[i].a,b=eg[i].b; 94 if(dep[a]<dep[b]) swap(a,b); 95 // a=getf(a),b=getf(b); 96 if(bm[a]<inf) ans[eg[i].ne]=bm[a]-1; 97 else ans[eg[i].ne]=-1; 98 }else{ 99 ans[eg[i].ne]=lca(eg[i].a,eg[i].b)-1; 100 } 101 } 102 for(i=1;i<=M;i++) 103 printf("%d ",ans[i]); 104 return 0; 105 }