求助站外题!
  • 板块学术版
  • 楼主RainSpark
  • 当前回复3
  • 已保存回复3
  • 发布时间2022/2/10 18:07
  • 上次更新2023/10/28 09:00:34
查看原帖
求助站外题!
352603
RainSpark楼主2022/2/10 18:07

Ht7yKH.png


现场20pts~30pts代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#define N 1010
using namespace std;
bool g[N][N];
int n,idx;
int fa[2*N];
int maxx[N],minn[N];
pair<int,int>res[2*N];
//并查集 
inline int search(int x){if(fa[x]!=x){fa[x]=search(fa[x]);}return fa[x];}
inline void uni(int x,int y){x=search(x),y=search(x);fa[y]=x;}
inline bool judge(int x,int y){x=search(x),y=search(x);if(x==y){return true;}else{return false;}}
void add(int x,int y){
	if(g[x][y]==0){//如果没被加过 
		g[x][y]=g[y][x]=1;//加边 
		res[++idx].first=x;//进入输出序列 
		res[idx].second=y;
		uni(x,y);//并查集合并 
	}
}
void ret(){//输出函数 
	sort(res+1,res+idx+1);//排序,防止后续加边影响结果 
	for(int i=1;i<=idx;i++)
		cout<<res[i].first<<' '<<res[i].second<<endl;
}
int main(){
	freopen("tree.in","r",stdin);freopen("tree.out","w",stdout);
	cin>>n;
	for(int i=1;i<=n;i++)//初始化并查集 
		fa[i]=i;
	for(int i=1;i<=n;i++){
		cin>>minn[i]>>maxx[i];
		add(i,minn[i]);
		add(i,maxx[i]);//加边 
	}
	if(idx>n-1){//如果边太多,不行 
		cout<<-1;
		return 0;
	}else if(idx==n-1){//如果恰好,直接输出 
		ret();
		return 0; 
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==j)
				continue;
			if(g[i][j]==0 && g[j][i]==0 && judge(i,j)==false && minn[i]<=j && maxx[i]>=j && minn[j]<=i && maxx[j]>=i){//边没有加入,不在同一集合中,相互不触犯最大和最小值 
				//printf("add %d and %d!\n",i,j);
				add(i,j);
				if(idx==n-1){//如果够了 
					ret();
					return 0;
				}
			}
		}
	}
	cout<<-1<<endl;
	fclose(stdin);fclose(stdout);
	//cout<<idx<<endl;
	return 0;
}

我的思路是先将能加入的边加入,判重,用并查集合并点,并记录已经加入的边数。完成后判断边数是否满足n-1,满足就输出,大于输出-1,否则就再加边直到有n-1条边。加的过程中判断重复,有没有在同一集合,有没有破坏样例的最大最小值。但是只有#0,#2过了,#1输出-1。请大佬看看有什么问题?(错误目前定位在双层循环的if)

2022/2/10 18:07
加载中...