1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| #include<bits/stdc++.h> using namespace std; const int max_n=50004,max_m=500005; inline int read(){ int x=0;bool w=0;char c=getchar(); while(c<'0' || c>'9') w|=c=='-',c=getchar(); while(c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return w?-x:x; } inline void write(int x){ if(x<0){ puts("Impossible"); return; } if(x>9) write(x/10); putchar(x%10^48); }
int n,m,s,k,m1,m2;
struct edge{ int u,v,w; bool operator < (const edge &b) const{ edge a=*this; return a.w<b.w; } }e1[max_m],e2[max_m]; inline edge makee(int x,int y,int z){ edge res; res.u=x,res.v=y,res.w=z; return res; }
struct par{ int x,y; }; inline par makep(int x,int y){ par res; res.x=x,res.y=y; return res; }
struct Union{ int fa[max_n],sz[max_n],n; inline void init(int x){ n=x; for(register int i=1;i<=n;++i) fa[i]=i,sz[i]=1; } inline int find(int x){ if(x==fa[x]) return x; return fa[x]=find(fa[x]); } inline bool merge(int x,int y){ x=find(x),y=find(y); if(x==y) return 0; if(sz[x]>sz[y]) x^=y^=x^=y; sz[y]+=sz[x],fa[x]=y; return 1; } }uf;
inline par check(int mid){ if(mid) for(register int i=1;i<=m1;++i) e1[i].w+=mid; uf.init(n); int res1=0,res2=0; for(register int i=1,j1=1,j2=1;i<n;){ if(j1>m1 && j2>m2 && i<n-1) return makep(-1,-1); if(j1<=m1 && (j2>m2 || e1[j1].w<=e2[j2].w)){ int u=e1[j1].u,v=e1[j1].v; if(uf.merge(u,v)){ ++res1,res2+=e1[j1].w, ++i; } ++j1; } else if(j2<=m2 || j1>m1){ int u=e2[j2].u,v=e2[j2].v; if(uf.merge(u,v)){ res2+=e2[j2].w, ++i; } ++j2; } } if(mid) for(register int i=1;i<=m1;++i) e1[i].w-=mid; return makep(res1,res2-res1*mid); }
inline int erfen(int l,int r){ --l,++r;int ans=0; while(l<r-1){ int mid=(l+r)>>1;par res=check(mid); if(res.x==k) l=mid,ans=mid; else if(res.x<k) r=mid; else l=mid; } par res=check(ans); if(res.x!=k) return -1; return res.y; }
signed main(){
n=read(),m=read(),s=read(),k=read(); for(register int i=1;i<=m;++i){ int u=read(),v=read(),w=read(); if(u==s || v==s) e1[++m1]=makee(u,v,w); else e2[++m2]=makee(u,v,w); } sort(e1+1,e1+1+m1),sort(e2+1,e2+1+m2); write(erfen(-30000,30000)); return 0; }
|