编程语言
首页 > 编程语言> > 国王的烦恼 蓝桥算法真题 并查集 java实现

国王的烦恼 蓝桥算法真题 并查集 java实现

作者:互联网

package qs;

/*
 * 
 * 测试数据为:
4 4
1 2 2
1 3 2
2 3 1
3 4 3
 * 
 * 
 * 
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;

public class testunionfind {
   
	static int s[];
   
  // static Bridge[] b=new Bridge[1000000+1];  这个数组排序无力,去掉,数据结构选择有问题
  static ArrayList<Bridge> blist=new ArrayList<Bridge>();
   
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       Scanner sc=new Scanner(System.in);
       int n=sc.nextInt();//小岛的个数
       int m=sc.nextInt(); //桥的数目
       s=new int[n+1];//下标0没有使用
       for(int i=1;i<=m;i++)    //读取m个桥的信息
       {
    	  Bridge bdg=new Bridge();
    	   bdg.a=sc.nextInt();
    	   bdg.b=sc.nextInt();
    	   bdg.t=sc.nextInt();
    	   blist.add(bdg);
       }	
       System.out.println(blist);//这一条是测试语句
       
        sort(blist);   //按天数排序   blist传给参数blist2后,不知道能不能实现排序的目的??
       //传参行不行???????
//       Collections.sort(blist,new Comparator<Bridge>(){
//			//override
//			public int compare(Bridge o1,Bridge o2){
//				return o2.t-o1.t;
//			}
//		});
       System.out.println(blist);
       init(n);   //先把小岛孤立的初始化为分散的并查集
       
       int a=-1;  //a用来判断前后抗议的天数是不是在同一天
       int sum=0; //sum用来表示抗议的天数
       for(int i=0;i<m;i++)  //倒叙得到m个桥,jingxing合并。合并时并查集-1,则抗议+1
       {   //得到第i个桥梁,它可以把两个小岛合并
    	  int b= mergee(blist.get(i).a,blist.get(i).b);    //把桥两端的岛屿合并
    	   
    	 if(b==1)//如果不属于一个集合而合并成功为一个集合
    	 {
    		 if(blist.get(i).t!=a)//与上一个抗议的日期不在同一天
    		 {sum++;
    		 a=blist.get(i).t;
    		 }
    	 }
       }
       
       System.out.println("sum="+sum);
       
	}

	
	
	//把桥按照天数逆序排序,逆向思维进行建立桥梁  每当建立一个桥梁,集合减少,说明没有这所桥梁时,
	//有两个孤立的集合存在,那么老百姓无法过桥到另外一座岛屿上,则老百姓在抱怨
	// 传参可
	private static void sort(ArrayList<Bridge> blist2) {
		Collections.sort(blist2,new Comparator<Bridge>(){
			//override
			public int compare(Bridge o1,Bridge o2){
				return o2.t-o1.t;
			}
		});
	}
	
	//




	private static int mergee(int x,int y) {   //并查集把有关系的和并在一起
		// TODO Auto-generated method stub
		x=findx(x);
		System.out.println(x);
		y=findx(y);
		System.out.println(y);
		if(x!=y)
			{s[x]=y;
			return 1;//return 1说明本来是不连通的(不在一个集合中的)
			}
		else 
			return 0;//return 0说明本来是在一个集合中的
	}

	
	private static int findx(int x)   //并查集查询并优化
	{  if(x!=s[x])
		  s[x]=findx(s[x]); //查询并优化
	   return s[x];
	}

	public static void init(int n)  //并查集初始化
	{
		for(int i=1;i<=n;i++)
		{s[i]=i;       //s[]是并查集的基本数据结构
	System.out.println("s[i]"+s[i]);
		}
			
	}
	
	
	
}




class Bridge{
	//Bridge是个对象   a,b, 是桥连接的小岛的号。t是 天数
	 public int a,b,t;
	public Bridge(){
		
	}
	public Bridge(int a,int b,int t)
	{this.a=a;
	this.b=b;
	this.t=t;}
	
	public String toString()
	{return a+" "+b+" "+t;}
	
}

标签:Bridge,java,真题,int,查集,蓝桥,static,new,return
来源: https://blog.csdn.net/julyyy123/article/details/123586911