参考大佬的博客,写的很好https://blog.youkuaiyun.com/mmk27_word/article/details/85076236?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160159374419195188335389%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=160159374419195188335389&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v3~pc_rank_v2-5-85076236.first_rank_ecpm_v3_pc_rank_v2&utm_term=Gym±+101911G&spm=1018.2118.3001.4187
题目
Input
4
3 4
1 4
3 4
Output
YES
1 3
3 2
2 4
Input
3
1 3
1 3
Output
NO
Input
3
1 2
2 3
Output
NO
题意:给出一个数n,下面是n-1行,每行两个数,分别表示一颗可能存在的树消去第i条边后两段线中最大的顶点.问:这棵树是否存在,存在的话按连接顺序打印n-1行,每行为相连接的顶点.否则输出NO.
思路:首先我们可以确定每一行中应该有一个n,否则树不存在,我们把每行中较小的顶点存起来从小到大连接.
AC code
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<sstream>
#include<queue>
#include<stack>
using namespace std;
set<int>s;
int main()
{
ios::sync_with_stdio(0);
int n,a,bb,flag=1,b[1200],c[1200];
cin>>n;
for(int i=1;i<n;i++)
{
cin>>a>>bb;
int g=min(a,bb);
if(a!=n&&bb!=n)flag=0;//每行中一定有一个n
s.insert(i);
b[i]=g;//存较小的数
}
if(!flag)
{
printf("NO\n");
return 0;
}
sort(b+1,b+n);
c[1]=b[1];
s.insert(n);
s.erase(b[1]);
for(int i=2;i<n;i++)
{
if(b[i]==b[i-1])//相等时就看是否还有较小的数
{
int p=*s.begin();
if(p<b[i])
{
c[i]=p;
s.erase(p);
}
else
{
printf("NO\n");
return 0;
}
}
else//不等的话直接连接
{
c[i]=b[i];
s.erase(b[i]);
}
}
c[n]=n;
printf("YES\n");
for(int i=2;i<=n;i++)printf("%d %d\n",c[i-1],c[i]);
}