MnZn求助,wqs二分过不了hack
查看原帖
MnZn求助,wqs二分过不了hack
258178
Benzenesir楼主2023/8/2 17:22
// Problem: P5633 最小度限制生成树
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P5633
// Memory Limit: 128 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <bitset>
#include <stack>
#include <tuple>
#include <bitset>
#define ll long long
#define ull unsigned long long
#define ld long double
#define fp(a,b,c) for(ll a=b;a<=c;a++)
#define fd(a,b,c) for(ll a=b;a>=c;a--)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define inf 0x3f3f3f3f3f3f3f3f
#define base 127
#define mod 1000000007
#define eb emplace_back
#define pb pop_back
#define y1 y114
#define y0 y514
#define x1 x114
#define x0 x514
#define fill(x,y) memset(x,y,sizeof(x))
#define mp make_pair

using namespace std;

inline int rd(){
	int x = 0, f = 1;char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-')f = -1;ch = getchar();}
	while(ch >= '0' && ch <= '9')x = (x<<1) + (x<<3) + (ch^48),ch = getchar();
	return x * f;}
inline ll lrd(){
	ll x = 0, f = 1;char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-')f = -1;ch = getchar();}
	while(ch >= '0' && ch <= '9')x = (x<<1) + (x<<3) + (ch^48),ch = getchar();
	return x * f;}
inline int logx(int n) {  
  int result = 0;  
  if(n&0xffff0000) {result += 16; n >>= 16; }  
  if(n&0x0000ff00) {result += 8; n >>= 8; }  
  if(n&0x000000f0) {result += 4; n >>= 4; }  
  if(n&0x0000000c) {result += 2; n >>= 2; }  
  if(n&0x00000002) {result += 1; n >>= 1; }  
  return result; 
}
const int maxN=5*1e5+10;
int n,m,s,k;
int f[maxN];
ll ans=0;
struct node{
	int u,v;
	ll w;
};
vector<node> v1,v2;

bool operator <(node x,node y){
	return x.w<y.w;
}

inline int acc(int x){
	if(f[x]==x) return x;
	return f[x]=acc(f[x]);
}

inline ll check(ll val){
	vector<node> v;
	auto p=v1.begin();
	for(node x:v2){
		while(p!=v1.end()&&(p->w)<(ll)x.w-val)
			v.eb(*p),++p;
		v.eb(node{x.u,x.v,(ll)x.w-val});
	}
	while(p!=v1.end()) v.eb(*p),++p;
	ll cnt1=0,cnt2=0;
	ans=0;
	fp(i,1,n) f[i]=i;
	for(node x:v){
		int u=x.u,v=x.v;
		if(acc(u)==acc(v)) continue ;
		cnt1++;
		if(u==s||v==s) cnt2++;
		u=acc(u),v=acc(v);
		f[u]=v;
		ans+=x.w;
		if(cnt1==n-1) break;
	}
	ans+=(val*cnt2);
	//cout << cnt2 << ' '<< ans<< endl; 
	return cnt2;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0); 
	n=rd(),m=rd(),s=rd(),k=rd();
	fp(i,1,n) f[i]=i;
	fp(i,1,m){
		int u=rd(),v=rd(),w=rd();
		if(acc(u)!=acc(v)) f[acc(u)]=acc(v);
		if(u==s||v==s) v2.eb(node{u,v,w});
		else v1.eb(node{u,v,w});
	}
	sort(v1.begin(),v1.end());
	sort(v2.begin(),v2.end());
	ll l=-inf,r=inf;
	ll res=0;
	if(v2.size()<k){
		cout << "Impossible" << endl;
		return 0;
	}
	
	fp(i,2,n) if(acc(i)!=acc(1)) {
		cout << "Impossible" << endl;
		return 0;
	}
	ll minx=-inf,maxx=-inf;
	ll d;
	while(l<=r){
		ll mid=(l+r)>>1;
	///	cout <<l<<" "<<r <<" " <<mid << endl;
		d=check(mid);
		if(minx==-inf) minx=d;
		if(maxx==-inf) maxx=d;
		minx=min(minx,d);
		maxx=max(maxx,d);
		//cout << d << endl;
		if(d<=k)
			res=ans,l=mid+1;
		else r=mid-1;
	}
	if(minx<=k&&k<=maxx) {
		cout << res << endl;
		return 0;
	}
	cout << "Impossible" << endl;
	
	
	return 0;
} 

第三个 hack 过不去

2023/8/2 17:22
加载中...