解题思路:
总的根数为m*n个,通过并查集将能连起来的点都连起来,同时每连一次只要没有形成闭合的环,根的总数就会少一个。python实现超时了,同样的思路用java实现AC了。
python参考代码:
m,n = map(int,input().split()) k = int(input()) parent = [-1 for _ in range(m*n+1)] #初始化各个节点的父节点为-1,开始谁都是根节点 rank = [0 for _ in range(m*n+1)] #记录树的长度 num = n*m def find(x,parent): #查找根节点 if parent[x]==-1: return x else: while parent[x] != -1: x = parent[x] return x for _ in range(k): x,y = map(int,input().split()) xRoot = find(x,parent) yRoot = find(y,parent) if xRoot!= yRoot: #合并 if rank[xRoot]>rank[yRoot]: parent[yRoot] = xRoot elif rank[yRoot] > rank[xRoot]: parent[xRoot] = yRoot elif rank[xRoot] == rank[yRoot]: parent[yRoot] = xRoot num -= 1 print(num)
java参考代码:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scan = new Scanner(System.in); int m,n,k; m = scan.nextInt(); n = scan.nextInt(); k = scan.nextInt(); int num = m*n; int[] parent = new int[num+1]; int[] rank = new int[num+1]; init(parent); // System.out.println(parent[1]); for (int i = 0; i < k; i++) { int x,y,xRoot,yRoot; x = scan.nextInt(); y = scan.nextInt(); xRoot = find(x,parent); yRoot = find(y,parent); if(xRoot != yRoot) { if (rank[xRoot]>rank[yRoot]) { parent[yRoot] = xRoot; }else if(rank[yRoot]>rank[xRoot]){ parent[xRoot] = yRoot; }else if(rank[yRoot]==rank[xRoot]) { parent[yRoot] = xRoot; } num--; } } System.out.println(num); } /** * 初始化压缩数组 * @param parent */ public static void init(int[] parent) { for (int i = 0; i < parent.length; i++) { parent[i] = -1; } } /** * 查找根节点 * @param x * @param parent * @return */ public static int find(int x,int[] parent) { if(parent[x] == -1) { return x; }else { while(parent[x] != -1) { x = parent[x]; } } return x; } }
0.0分
2 人评分
Tom数 (C语言代码)浏览:2009 |
C语言程序设计教程(第三版)课后习题8.9 (C++代码)(其实不需要开数组,一个一个字符读入并判断就好了)浏览:924 |
化学品问题 (C语言代码)浏览:1329 |
C语言训练-字符串正反连接 (C语言代码)浏览:688 |
C语言训练-素数问题 (C语言代码)浏览:1654 |
数组输出 (C语言代码)错误???浏览:558 |
C语言程序设计教程(第三版)课后习题6.6 (C语言代码)浏览:624 |
WU-printf基础练习2 (C++代码)浏览:1999 |
printf基础练习2 (C语言代码)浏览:644 |
哥德巴赫曾猜测 (C语言代码)浏览:2315 |