万万没想到这道题还能用并查集来做,真的是长见识了。
题目的解法是将给的坐标分成两个点,然后将这两个点串起来,当然每次新输入一个点除了要将这两个点串起来,还要看看能不能和上面的点串起来。
如果发现某些点最后串不成一个环,那么称它为一条路径,那么此时答案数就是这条路径上的点数,因为这样所有的点都不用因为其他点而移动到某一个地方从而多走出某一步。而当能够串成一个环时,那么某一个点就要让步给其他点,从而就要多走一步这个环里面的所有点才能到达相应的位置。
当然还有一个注意点就是对于已经在对角线上的点就不要动它了。
连接点使用并查集来维护。
#include <iostream> #include <algorithm> using namespace std; const int N = 200050; struct Node{ int x, y; }node[N]; int fa[N]; int find(int x){ if(x == fa[x]) return x; else return fa[x] = find(fa[x]); } void solve(){ for(int i = 1; i <= 200010; i ++) fa[i] = i; int n, m, cnt = 0, ver = 1; cin >> n >> m; for(int i = 1; i <= m; i ++){ int x, y; cin >> x >> y; if(x == y) continue; else node[ver].x = x, node[ver].y = y; int fx = find(node[ver].x); int fy = find(node[ver].y); if(fx != fy) fa[fx] = fy; else cnt ++; ver ++; } cout << cnt + ver - 1 << endl; return; } int main(){ int t; cin >> t; while(t --){ solve(); } return 0; }