• HDU 1879 继续畅通工程 (Prim(普里姆算法)+Kruskal(克鲁斯卡尔))


    继续畅通工程

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 10765    Accepted Submission(s): 4704


    Problem Description
    省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
     
    Input
    测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。

    当N为0时输入结束。
     
    Output
    每个测试用例的输出占一行,输出全省畅通需要的最低成本。
     
    Sample Input
    3 1 2 1 0 1 3 2 0 2 3 4 0 3 1 2 1 0 1 3 2 0 2 3 4 1 3 1 2 1 0 1 3 2 1 2 3 4 1 0
     
    Sample Output
    3 1 0
     
    Author
    ZJU
     
    Source
     

    这道题虽然是一道模板题,但是有一点要注意:

    不能使用  Scanner sc = new Scanner(new BufferedInputStream(System.in));  和

             System.out.println();

    否则会超时;

    推荐使用:  BufferedReader bu=new BufferedReader(new InputStreamReader(System.in));   和

                          PrintWriter pw=new PrintWriter(new OutputStreamWriter(System.out),true);

    克鲁斯卡尔

    import java.io.*;
    import java.util.*;
    public class Main {
    	public  int n,m,sum;
    	public  ArrayList<kr> ay=new ArrayList<kr>();;
    	public  int pattern[];
    	PrintWriter pw;
    	public static void main(String[] args) throws IOException{
    		new Main().work();
    	}
    	public void work() throws IOException{
    		BufferedReader bu=new BufferedReader(new InputStreamReader(System.in));
    		pw=new PrintWriter(new OutputStreamWriter(System.out),true);
    		n=Integer.parseInt(bu.readLine());
    		while(n!=0){
    			m=(n*(n-1))>>1;
    			ay.clear();
    			sum=0;
    			for(int i=0;i<m;i++){
    				String str[]=bu.readLine().split(" ");
    				int a=Integer.parseInt(str[0]);
    				int b=Integer.parseInt(str[1]);
    				int c=Integer.parseInt(str[2]);
    				int d=Integer.parseInt(str[3]);
    				if(d==1)
    					c=0;
    				kr k=new kr(a,b,c);
    				ay.add(k);
    			}
    			Collections.sort(ay);
    			Kruskral();
    			pw.println(sum);
    			n=Integer.parseInt(bu.readLine());
    		}
    	}
    	public  void Kruskral(){
    		pattern=new int[n+1];
    		for(int i=1;i<=n;i++){
    			pattern[i]=i;
    		}
    		for(int i=0;i<ay.size();i++){
    			union(ay.get(i).a,ay.get(i).b,ay.get(i).c);
    		}
    	}
    	public  void union(int a,int b,int c){
    		int aa=find(a);
    		int bb=find(b);
    		if(aa==bb)
    			return;
    		if(aa>bb){
    			pattern[bb]=aa;
    			sum+=c;
    			//pw.println(sum);
    		}
    		else{
    			pattern[aa]=bb;
    			sum+=c;
    		}
    	}
    	public  int find(int x){
    		int k,r,s;
    		r=x;
    		while(r!=pattern[r]){
    			r=pattern[r];
    		}
    		k=x;
    		while(k!=r){
    			s=pattern[k];
    			pattern[k]=r;
    			k=s;
    		}
    		return r;
    	}
    }
    class kr implements Comparable<kr>{
    	int a;
    	int b;
    	int c;
    	kr(int a,int b,int c){
    		this.a=a;
    		this.b=b;
    		this.c=c;
    	}
    	public int compareTo(kr o) {
    		return this.c>o.c?1:-1;
    	}
    }


     

    普利姆算法

    import java.io.*;
    import java.util.*;
    
    public class Main {
    	public  int MAX=2000000;
    	public  int map[][];
    	public  int n,m;
    	PrintWriter pw;
    	public static void main(String args[]) throws IOException{
    		new Main().work();
    	}
    	public  void work() throws IOException{
    		//Scanner sc=new Scanner(new BufferedInputStream(System.in));
    		BufferedReader bu=new BufferedReader(new InputStreamReader(System.in));
    		pw=new PrintWriter(new OutputStreamWriter(System.out),true);
    		n=Integer.parseInt(bu.readLine());
    		while(n!=0){
    			m=(n*(n-1))>>1;
    			map=new int[n+1][n+1];
    			for(int i=1;i<=n;i++){
    				for(int j=1;j<=n;j++){
    					map[i][j]=MAX;
    				}
    			}
    			
    			for(int i=1;i<=m;i++){
    				String str[]=bu.readLine().split(" ");
    				int a=Integer.parseInt(str[0]);
    				int b=Integer.parseInt(str[1]);
    				int c=Integer.parseInt(str[2]);
    				int d=Integer.parseInt(str[3]);
    				if(d==1){
    					c=0;
    				}
    				if(map[a][b]>c)
    					map[a][b]=map[b][a]=c;
    			}
    			getDistance();
    			n=Integer.parseInt(bu.readLine());
    		}
    	}
    	////Prim(普里姆算法)
    	public  void getDistance(){
    		int k=0,sum=0;
    		int dis[]=new int[n+1];
    		int mark[]=new int[n+1];
    		for(int i=2;i<=n;i++){
    			dis[i]=map[1][i];//初始化起点到其他点之间的距离
    		}
    		mark[1]=1;
    		for(int i=1;i<n;i++){
    			int min=MAX;
    			// 每次循环寻找的最短的边
    			for(int j=2;j<=n;j++){
    				if(mark[j]==0&&dis[j]<min){
    					min=dis[j];
    					k=j;
    				}
    			}
    			if(min==MAX) break;
    			mark[k]=1;
    			sum+=dis[k];
    			//到一个新的点,从新计算到其他点之间的距离
    			for(int j=2;j<=n;j++){
    				if(mark[j]==0&&dis[j]>map[k][j])
    					dis[j]=map[k][j];
    			}
    		}
    			pw.println(sum);
    	}
    }
    


     

  • 相关阅读:
    文件的初级功能
    Scanner的用法
    界面制作小例
    初学Java感想
    el-table合计栏未显示的问题
    推荐一些团队博客和个人博客地址
    大数加法
    汇编语言画圆
    Java一个简单的文件工具集
    css选择器
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3313284.html
Copyright © 2020-2023  润新知