建议加强数据
查看原帖
建议加强数据
213173
小木虫楼主2022/4/28 19:46

rt,我在写题解的时候代码里犯了一个小错误,在LOJ上能被一组很小很小的数据卡掉,但在洛谷上可以通过,数据过水。
原代码:

#include <bits/stdc++.h>
using namespace std;
const int MAXN=4e5+10;
int n,m;int f[MAXN];
struct EDGE{int u,v,w;}edge[MAXN];
int st[MAXN][21];int fa[MAXN];int value[MAXN];
int root;int son[MAXN][2];bool chain[MAXN];
int s[MAXN];int t[MAXN];int deep[MAXN];
int find(int x){
	if(fa[x]==x)return x;
	else return fa[x]=find(fa[x]);
}
void merge(int x,int y,int i){
	fa[x]=y;
	if(s[y]==0&&t[y]==0){
		chain[y]=chain[x];
		s[y]=s[x];t[y]=t[x];
		return;
	}
	if(chain[x]&&chain[y]){
		if(s[x]==edge[i].u&&t[y]==edge[i].v)t[y]=t[x];
		else if(s[x]==edge[i].v&&t[y]==edge[i].u)t[y]=t[x];
		else if(t[x]==edge[i].u&&t[y]==edge[i].v)t[y]=s[x];
		else if(t[x]==edge[i].v&&t[y]==edge[i].u)t[y]=s[x];
		else if(s[x]==edge[i].u&&s[y]==edge[i].v)s[y]=t[x];
		else if(s[x]==edge[i].v&&s[y]==edge[i].u)s[y]=t[x];
		else if(t[x]==edge[i].u&&s[y]==edge[i].v)s[y]=s[x];
		else if(t[x]==edge[i].v&&s[y]==edge[i].u)s[y]=s[x];
		else chain[y]=0;
	}else{
		chain[y]=0;s[y]=t[y]=-1;
	}
}
bool cmp(EDGE a,EDGE b){return a.w<b.w;}
void dfs(int u){
	//cout<<u<<" "<<son[u][0]<<" "<<son[u][1]<<endl;
	deep[u]=deep[f[u]]+1;
	st[u][0]=f[u];
	for(int i=1;i<=20;i++)st[u][i]=st[st[u][i-1]][i-1];
	if(son[u][0])dfs(son[u][0]);
	if(son[u][1])dfs(son[u][1]);
}
int LCA(int x,int y){
	if(deep[x]<deep[y])swap(x,y);
	for(int i=20;i>=0;i--){
		if(deep[st[x][i]]>=deep[y])x=st[x][i];
	}
	if(x==y)return x;
	for(int i=20;i>=0;i--){
		if(st[x][i]!=st[y][i]){
			x=st[x][i];y=st[y][i];
		}	
	}
	return f[x];
}
void init(int N,int M,vector <int> U,vector <int> V,vector <int> W){
	n=N;m=M;
	for(int i=0;i<m;i++)
		edge[i+1]=(EDGE){U[i]+1,V[i]+1,W[i]};
	for(int i=1;i<=n+m;i++)fa[i]=i;
	for(int i=1;i<=n;i++)chain[i]=1,s[i]=i,t[i]=i;
	sort(edge+1,edge+1+m,cmp);
	for(int i=1;i<=m;i++){
		int x=find(edge[i].u);
		int y=find(edge[i].v);
		value[i+n]=edge[i].w;
		if(x==y){
			f[x]=i+n;son[i+n][0]=x;
			merge(x,i+n,i);chain[i+n]=0;
			continue;
		}
		f[x]=f[y]=i+n;son[i+n][0]=x;son[i+n][1]=y;
		merge(x,i+n,i);
		merge(y,i+n,i);
	}
	//for(int i=1;i<=m;i++)cout<<edge[i].u<<" "<<edge[i].v<<" "<<chain[i+n]<<endl;
	dfs(n+m);
}
int res;
int check(int x,int y){
	for(int i=20;i>=0;i--){
		if(st[x][i]==0)continue;
		if((1<<i)<=y){
			x=st[x][i];y-=(1<<i);
		}
	}
	res=value[x];
	if(y)return -1;
	if(chain[x])return 0;
	return 1;
}
int getMinimumFuelCapacity(int x,int y){
	x++;y++;
	int lca=LCA(x,y);
	//cout<<lca<<endl;
	int l=0;int r=n;
	while(l<r){
		int mid=(l+r)/2;
		int c=check(lca,mid);
		if(c==-1)r=mid-1;
		if(c==0)l=mid+1;
		if(c==1)r=mid;
	}
	if(!check(lca,l))return -1;
	check(lca,l);
	return res;
}
//int main(){
//	int n,m,q,u,v,w;
//	vector <int> U;U.clear();
//	vector <int> V;V.clear();
//	vector <int> W;W.clear();
//	cin>>n>>m;
//	for(int i=1;i<=m;i++){
//		cin>>u>>v>>w;
//		U.push_back(u);
//		V.push_back(v);
//		W.push_back(w);
//	}
//	init(n,m,U,V,W);
//	cin>>q;
//	for(int i=1;i<=q;i++){
//		cin>>u>>v;
//		cout<<getMinimumFuelCapacity(u,v)<<endl;
//	}
//	return 0;
//}

Hack:
3 2
0 1 3
0 2 5
4
0 1
0 2
1 2
0 2
改后代码:

#include <bits/stdc++.h>
using namespace std;
const int MAXN=4e5+10;
int n,m;int f[MAXN];
struct EDGE{int u,v,w;}edge[MAXN];
int st[MAXN][21];int fa[MAXN];int value[MAXN];
int root;int son[MAXN][2];bool chain[MAXN];
int s[MAXN];int t[MAXN];int deep[MAXN];
int find(int x){
	if(fa[x]==x)return x;
	else return fa[x]=find(fa[x]);
}
void merge(int x,int y,int i){
	fa[x]=y;
	if(s[y]==0&&t[y]==0){
		chain[y]=chain[x];
		s[y]=s[x];t[y]=t[x];
		return;
	}
	if(chain[x]&&chain[y]){
		if(s[x]==edge[i].u&&t[y]==edge[i].v)t[y]=t[x];
		else if(s[x]==edge[i].v&&t[y]==edge[i].u)t[y]=t[x];
		else if(t[x]==edge[i].u&&t[y]==edge[i].v)t[y]=s[x];
		else if(t[x]==edge[i].v&&t[y]==edge[i].u)t[y]=s[x];
		else if(s[x]==edge[i].u&&s[y]==edge[i].v)s[y]=t[x];
		else if(s[x]==edge[i].v&&s[y]==edge[i].u)s[y]=t[x];
		else if(t[x]==edge[i].u&&s[y]==edge[i].v)s[y]=s[x];
		else if(t[x]==edge[i].v&&s[y]==edge[i].u)s[y]=s[x];
		else chain[y]=0;
	}else{
		chain[y]=0;s[y]=t[y]=-1;
	}
}
bool cmp(EDGE a,EDGE b){return a.w<b.w;}
void dfs(int u){
	//cout<<u<<" "<<son[u][0]<<" "<<son[u][1]<<endl;
	deep[u]=deep[f[u]]+1;
	st[u][0]=f[u];
	for(int i=1;i<=20;i++)st[u][i]=st[st[u][i-1]][i-1];
	if(son[u][0])dfs(son[u][0]);
	if(son[u][1])dfs(son[u][1]);
}
int LCA(int x,int y){
	if(deep[x]<deep[y])swap(x,y);
	for(int i=20;i>=0;i--){
		if(deep[st[x][i]]>=deep[y])x=st[x][i];
	}
	if(x==y)return x;
	for(int i=20;i>=0;i--){
		if(st[x][i]!=st[y][i]){
			x=st[x][i];y=st[y][i];
		}	
	}
	return f[x];
}
void init(int N,int M,vector <int> U,vector <int> V,vector <int> W){
	n=N;m=M;
	for(int i=0;i<m;i++)
		edge[i+1]=(EDGE){U[i]+1,V[i]+1,W[i]};
	for(int i=1;i<=n+m;i++)fa[i]=i;
	for(int i=1;i<=n;i++)chain[i]=1,s[i]=i,t[i]=i;
	sort(edge+1,edge+1+m,cmp);
	for(int i=1;i<=m;i++){
		int x=find(edge[i].u);
		int y=find(edge[i].v);
		value[i+n]=edge[i].w;
		if(x==y){
			f[x]=i+n;son[i+n][0]=x;
			merge(x,i+n,i);chain[i+n]=0;
			continue;
		}
		f[x]=f[y]=i+n;son[i+n][0]=x;son[i+n][1]=y;
		merge(x,i+n,i);
		merge(y,i+n,i);
	}
	//for(int i=1;i<=m;i++)cout<<edge[i].u<<" "<<edge[i].v<<" "<<chain[i+n]<<endl;
	dfs(n+m);
}
int res;
int check(int x,int y){
	for(int i=20;i>=0;i--){
		if(st[x][i]==0)continue;
		if((1<<i)<=y){
			x=st[x][i];y-=(1<<i);
		}
	}
	res=value[x];
	if(y)return -1;
	if(chain[x])return 0;
	return 1;
}
int getMinimumFuelCapacity(int x,int y){
	x++;y++;
	int lca=LCA(x,y);
	//cout<<lca<<endl;
	int l=0;int r=n;
	while(l<r){
		int mid=(l+r)/2;
		int c=check(lca,mid);
		if(c==-1)r=mid-1;
		if(c==0)l=mid+1;
		if(c==1)r=mid;
	}
	if(check(lca,l)!=1)return -1;
	check(lca,l);
	return res;
}
//int main(){
//	int n,m,q,u,v,w;
//	vector <int> U;U.clear();
//	vector <int> V;V.clear();
//	vector <int> W;W.clear();
//	cin>>n>>m;
//	for(int i=1;i<=m;i++){
//		cin>>u>>v>>w;
//		U.push_back(u);
//		V.push_back(v);
//		W.push_back(w);
//	}
//	init(n,m,U,V,W);
//	cin>>q;
//	for(int i=1;i<=q;i++){
//		cin>>u>>v;
//		cout<<getMinimumFuelCapacity(u,v)<<endl;
//	}
//	return 0;
//}

就是改了一下判断-1的那一个if

2022/4/28 19:46
加载中...