There is only one simple path between any two points ⇔\leftrightarrow tree
So is to make the remaining points to form a tree, it is easy to find, as the number of lattice, the number of edges increased faster than the point, and K K will not be very large. So when the n∗m n*m is too big, it is impossible to make a tree. Rough estimate, 5∗105 5*10^5 is no solution.
Then there is the violent judgment. Direct and check the collection.
#include <cstdio> #include <cstring> #include <algorithm> using namespace std;
const int maxn=500005;
typedef long Long LL;
int _test,n,m,k,fa[maxn],tot_e;
BOOL VIS[MAXN];
int ID (int x,int y) {return (x-1) *m+y} int GETFA (int x) {return FA[X]==X?X:FA[X]=GETFA (fa[x));} bool Add (int x,int y) { if (vis[x]| |
Vis[y]) return true;
if (GETFA (x) ==GETFA (y)) return false;
tot_e++;
return FA[GETFA (x)]=GETFA (y), true;
BOOL Check () {tot_e=0;
for (int i=1;i<=n*m;i++) fa[i]=i; for (int i=1;i<=n;i++) {for (int j=1;j<=m;j++) {if (j<m) {if (!)
ADD (ID (I,J), ID (i,j+1)) return false; } else{if (!
ADD (ID (I,J), ID (i,1)) return false; } if (i<n) if (!
ADD (ID (I,J), ID (I+1,J)) return false; } int t=0;
for (int i=1;i<=n*m;i++) if (!vis[i]) T=GETFA (i);
for (int i=1;i<=n*m;i++) if (!VIS[I]&&GETFA (i)!=t) return false;
return true;
int main () { Freopen ("A.in", "R", stdin);
Freopen ("A.out", "w", stdout);
scanf ("%d", &_test);
while (_test--) {memset (vis,0,sizeof (VIS));
scanf ("%d%d%d", &n,&m,&k);
if (LL) n*m>500000 {printf ("no\n"); for (int i=1;i<=k;i++) scanf ("%*d%*d"); continue;}
for (int i=1;i<=k;i++) {int x,y; scanf ("%d%d", &x,&y);
Vis[id (x,y)]=true; } if (check ()) printf ("yes\n");
else printf ("no\n");
return 0; }