赛时写的神奇代码,大致思路是分成两组,然后只要有冲突就丢尽另外一组,如果还有冲突就判断为 NO。但发现会有两组都可以放的情况,我直接把它丢到队列里等一轮完后再次去判断,如果连续丢到队列的次数过多,就将它放入第一组。
这种神奇的贪心思路竟然过了,而且赛后也没有被 hack,请求大佬能够把它叉了 qwq。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#define init(x) memset (x,0,sizeof (x))
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
using namespace std;
const int MAX = 2e5 + 5;
const int MOD = 1e9 + 7;
inline int read ();
int t,n,cnt,a[MAX],b[MAX];
bool ok;
int main ()
{
//freopen (".in","r",stdin);
//freopen (".out","w",stdout);
t = read ();
while (t--)
{
n = read ();
ok = 1;
queue <pair <int,int> > q;
for (int i = 1;i <= n;++i)
{
int x = read (),y = read ();
a[i] = b[i] = 0;
q.push ({x,y});
}
while (!q.empty ())
{
int x = q.front ().first,y = q.front ().second;
q.pop ();
if (x == y) ok = 0;
else if ((a[x] || a[y]) && (b[x] || b[y])) ok = 0;
else if (!a[x] && !a[y] && (b[x] || b[y])) a[x] = a[y] = 1;
else if (!b[x] && !b[y] && (a[x] || a[y])) b[x] = b[y] = 1;
else if (cnt >= 10000) a[x] = a[y] = 1,cnt = 0;//就是这里比较神奇 赛后改为1000就过不了了
else ++cnt,q.push ({x,y});
}
if (ok) printf ("YES\n");
else printf ("NO\n");
}
return 0;
}
inline int read ()
{
int s = 0;int f = 1;
char ch = getchar ();
while ((ch < '0' || ch > '9') && ch != EOF)
{
if (ch == '-') f = -1;
ch = getchar ();
}
while (ch >= '0' && ch <= '9')
{
s = s * 10 + ch - '0';
ch = getchar ();
}
return s * f;
}