题目链接:
https://www.luogu.org/problemnew/show/UVA10763
题目分析:
本题我首先想到的做法是把每一个数都map一下,然后互相判断,例如a,b两人准备交换,那么m[a]=b,m[b]=a,最后再判断如果m[m[a]]=a就行,但是因为一个学生在双方都同意的情况下可以先后与多个学生交换,所以我的做法是:
先把每对学生都按照先小后大的顺序排好
if(a[i].x>a[i].y)swap(a[i].x,a[i].y);
然后把所以学生交换对都进行排序
sort(a+1,a+n+1,cmp);
其中排序按照先看第一个学生编号的大小,再看第二个。
int cmp(const ben &a,const ben &b)
{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
然后,即使有一人同多人交换,那么此时一对学生交换对的下一对应该是相同的了。
当然,因为交换是双向的,我们可以中间加一个特判
if(n%2==1)
{
printf("NO\n");
continue;
}
从而省去没必要的计算(注意此判断要在一组输入结束后)
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct ben
{
int x,y;
}a[500005];
int cmp(const ben &a,const ben &b)
{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
}
int main()
{
int n;
while(scanf("%d",&n)==1&&n!=0)
{
int cnt=0;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
if(a[i].x>a[i].y)swap(a[i].x,a[i].y);
}
if(n%2==1)
{
printf("NO\n");
continue;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i=i+2)
{
if(a[i].x==a[i+1].x&&a[i].y==a[i+1].y)
{
cnt++;
}
}
if(cnt==n/2)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
return 0;
}
求赞~