Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10765 Accepted Submission(s): 4704
这道题虽然是一道模板题,但是有一点要注意:
不能使用 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); } }