HNUCM-OJ(中等难度)--java实现

HNUCM-OJ刷题--java实现

  • 数列A1,A1,...,AN ,修改最少的数字,使得数列严格单调递增。
        • 思路:
        • 代码:
  • 问题 D: 矩阵连乘问题-求最优值
        • 代码:
  • 问题 E: 矩阵连乘问题-构造最优解
        • 代码:
  • 问题 F: 石子合并问题
        • 代码:
  • 问题 I: 病毒
        • 思路:
        • 代码
  • 今年暑假不AC
        • 代码
  • 最小生成树(Kruskal)
        • 思路
        • 代码
  • 牛牛的蛋糕
        • 思路:
        • 代码:
  • 尼科彻斯定理
        • 代码:
  • DNA序列
        • 思路:
        • 代码:
  • 问题 F: 隔离14天
        • 思路:
        • 代码:
  • 问题 H: 单源最短路径问题
          • 代码:

数列A1,A1,…,AN ,修改最少的数字,使得数列严格单调递增。

题目描述

数列A1,A1,…,AN ,修改最少的数字,使得数列严格单调递增。

输入

第 1 行,1 个整数 N 第 2 行,N 个整数 A1,A1,…,AN

。(1 ≤ N ≤ 10^5,1≤ Ai ≤10^9)

输出

1 个整数,表示最少修改的数字 。

样例输入 Copy

3
1 2 3
5
1 2 9 3 4

样例输出 Copy

0
1

思路:

维护一个单调队列,这个队列的元素是严格单调递增的,当我们增加一个新元素去和单调队列的最后一个元素比较,如果比最后一个元素大,就入队,否则,就将该元素插入到本应该在队列中的某一位置(二分)

代码:


import java.util.Scanner;

public class Main{
	static int n=500;
	static int r=0;
	static int arr[]=new int[n+1];
	static int temp[]=new int[n+1];
	public static int find(int x) {//二分查找某个元素应在的位置
		int mid, left=1,right=r;
		while(left<right) {
			 mid=(left+right)>>1;
        if(x==temp[mid]) 
            return mid;
        if(x>temp[mid])
            left=mid+1;
        else
            right=mid;
    }
    return right;
		}
		
    public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
  
        while(cin.hasNext()){
               int n=cin.nextInt();
               for(int i=1;i<=n;i++) {
            	   arr[i]=cin.nextInt();
               }//输入
               for(int i=1;i<=n;i++)
               {
                   if(arr[i]>temp[r])   
                	   temp[++r]=arr[i];//入队
                   else
                	   temp[find(arr[i])]=arr[i];//去查找该元素在队列中应在的位置
               }
               System.out.println(n-r);
               
                r=0;//使r重新回到0;继续下一次执行的初始化
               
 
     
        }
    }
}

问题 D: 矩阵连乘问题-求最优值

题目描述

使用动态规划算法求解矩阵连乘问题,输出最少乘法次数。

输入

每组数据包括两行,第一行为数组长度n,第二行为存储矩阵维数的一维数组。

输出

矩阵连乘最优计算次数。

样例输入 Copy

7
30 35 15 5 10 20 25

样例输出 Copy

15125

代码:

import java.util.Scanner;
 
public class Main{
     
     public static void martixChain(int p[],int m[][]) {
         int n=p.length-1;
         for(int i=1;i<=n;i++) {m[i][i]=0;}
         for(int r=2;r<=n;r++) {//长度
             for(int i=1;i<=n-r+1;i++) {//每一个对角线的元素个数
                 int j=i+r-1;//列
                 m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
                 for(int k=i+1;k<j;k++) {
                     int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
                      if (t < m[i][j]) {
                             m[i][j] = t;
                              }
 
 
                 }
                  
             }
              
         }
     }
    public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
       while(cin.hasNext()) {
           int n=cin.nextInt(); 
           int p[]=new int[n];//存维度
           for(int i=0;i<n;i++) {
               p[i]=cin.nextInt();
           }
           
           int  m[][]=new int[n][n];//m为存取最少存取次数
           martixChain(p,m);
           System.out.println(m[1][n-1]);
           
        }
}
}
 

问题 E: 矩阵连乘问题-构造最优解

题目描述

使用动态规划算法求解矩阵连乘问题。

输入

每组数据包括两行,第一行为数组长度n,第二行为存储矩阵维数的一维数组。

输出

矩阵连乘最优计算次序。

样例输入 Copy

7
30 35 15 5 10 20 25

样例输出 Copy

A[2:2] * A[3:3]
A[1:1] * A[2:3]
A[4:4] * A[5:5]
A[4:5] * A[6:6]
A[1:3] * A[4:6]

代码:

import java.util.Scanner;

public class Main{
	
	 public static void martixChain(int p[],int m[][],int s[][]) {
		 int n=p.length-1;
		 for(int i=1;i<=n;i++) {m[i][i]=0;}
		 for(int r=2;r<=n;r++) {//长度
			 for(int i=1;i<=n-r+1;i++) {//每一个对角线的元素个数
				 int j=i+r-1;//列
				 m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
				   s[i][j] = i;
				 for(int k=i+1;k<j;k++) {
					 int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
					  if (t < m[i][j]) {
			                 m[i][j] = t;
			                 s[i][j]=k;
			                  }
				 }
				 
			 }
			 
		 }
	 }
	 public static void traceback(int s[][],int i,int j) {
		 if(i==j)return ;
		 traceback(s, i, s[i][j]);
		 traceback(s, s[i][j]+1, j);

		  //A[2:2] * A[3:3]
		System.out.println("A["+i+":"+s[i][j]+"] *  A["+(s[i][j]+1)+":"+j+"]");
		 
		

	 }
    public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
       while(cin.hasNext()) {
    	   int n=cin.nextInt(); 
    	   int p[]=new int[n];//存维度
    	   for(int i=0;i<n;i++) {
    		   p[i]=cin.nextInt();
    	   }
    	  
    	   int  m[][]=new int[n][n];//m为存取最少存取次数
    	   int s[][]=new int[n][n];
    	   martixChain(p,m,s);
    	   traceback(s,1,n-1);
    	  
        }
}
}

问题 F: 石子合并问题

题目描述

在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数。求把所有石子合并成一堆的最小花费。例如:输入{1,2,3,4,5},输出33。【3+6+9+15=33】

输入

本题应该处理到文件尾,每组输入包括两行,第一行为石子堆的个数n,第二行则为每堆石子的个数。

输出

输出最小花费。

样例输入 Copy

5
1 2 3 4 5

样例输出 Copy

33

代码:

import java.util.Scanner;
 
public class Main{
     
         
    public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
       while(cin.hasNext()) {
           int n=cin.nextInt();
           int dp[][]=new int [n+1][n+1];
           int sum[][]=new int[n+1][n+1];
           int arr[]=new int[n+1];
           for(int i=1;i<=n;i++) {
               arr[i]=cin.nextInt();//输入
           }
           for(int i=1;i<n;i++)
            {
                sum[i][i]=arr[i];
                for(int j=i+1;j<=n;j++)
                {
                    sum[i][j]=sum[i][j-1]+arr[j];//合并区间i到j的结果
                }
            }
           for(int r=2;r<=n;r++)//区间长度为 r的最小值
            {
                for(int i=1;i<=n-(r-1);i++)//枚举区间长度的开头
                { 
                    int j=i+(r-1);//区间长度固定,根据开头求出结尾 
                    dp[i][j]=999999999;
                    for(int k=i;k<j;k++)//枚举出合并这段区间以前的最小花费
                    {
                        dp[i][j]=Math.min(dp[i][j],dp[i][k]+dp[k+1][j]);
                    }
                    dp[i][j] += sum[i][j];//加上这一段合并的花费
                }
            }
 
        System.out.println(dp[1][n]);
            
        }
}
}

问题 I: 病毒

时间限制: 3 Sec 内存限制: 128 MB

提交: 6 解决: 1 外部导入

提交状态讨论版

题目描述

你有一个日志文件,里面记录着各种系统事件的详细信息。自然的,事件的时间戳按照严格递增顺序排列(不会有两个事件在完全相同的时刻发生)。

遗憾的是,你的系统被病毒感染了,日志文件中混入了病毒生成的随机伪事件(但真实事件的相对顺序保持不变)。备份的日志文件也被感染了,但由于病毒采用的随机感染方法,主日志文件和备份日志文件在感染后可能会变得不一样。

给出被感染的主日志和备份日志,求真实事件序列的最长可能长度。

输入

输入第一行为数据组数T (T<=100)。每组数据包含两行,分别描述感染后的主日志和备份日志。每个日志文件的格式相同,均为一个整数n (1<=n<=1000)(代表感染后的事件总数)和n 个不超过100,000的正整数(表示感染后各事件的时间戳)。注意,感染后可能会出现时间戳完全相同的事件。

输出

对于每组数据,输出真实事件序列的最长可能长度。

样例输入 Copy

1
9 1 4 2 6 3 8 5 9 1
6 2 7 6 3 5 1

样例输出 Copy

3

思路:

最长递增子序列

代码

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
  
  
public class Main {
     static int f[][]= {};
     static int ans=0;
    public static void solve(int f[][],int a[],int b[],int n,int m) {
        for(int i=1; i<=n; i++){
            int v=0; //v代表b[k]
            for(int j=1; j<=m; j++){
              if(a[i]==b[j]) f[i][j]=v+1;
              else f[i][j]=f[i-1][j];
              //j即将增大为j+1,检查j能否进入新的决策集合
              if(b[j]<a[i]) v=Math.max(v,f[i-1][j]);
            }
        }
        for(int j=1; j<=m; j++) ans=Math.max(ans,f[n][j]);
    }
    public static void main(String[] args) {
        Scanner cin=new Scanner(System.in);
        {
           int T;
           T=cin.nextInt();
           while(T>0) {
               int n=cin.nextInt();
               int a[]=new int[n+1];
               for(int i=1;i<=n;i++) {
                   a[i]=cin.nextInt();
               }//第一个主日志
               int m=cin.nextInt();
               int b[]=new int[m+1];
               for(int i=1;i<=m;i++) {
                   b[i]=cin.nextInt();
               }//第二个备份日志
               f=new int[n+1][m+1];
               solve(f,a,b, n, m);
              
               System.out.println(ans);
               ans=0;
               for(int i=1;i<=n;i++) {
                   for(int j=1;j<=m;j++) {
                       f[i][j]=0;
                   }
               }
               T--;
           }
        }
    }
      
  
}

今年暑假不AC

题目描述

“今年暑假不AC?”
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%…”

确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)

输入

输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。

输出

对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。

样例输入 Copy

12
1 3
3 4
0 7
3 8
15 19
15 20
10 15
8 18
6 12
5 10
4 14
2 9
0

样例输出 Copy

5

代码

import java.awt.List;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
class Tv
{
    int start;
    int end;
    public Tv(int start,int end) {
    	this.start=start;
    	this.end=end;
    }
};//定义一个结构体,存开始和结束时间
//排序
class cmp implements Comparator<Tv>{

	@Override
	public int compare(Tv a, Tv b) {
		if(a.end<b.end) {
			return 1;
		}else {
			return -1;
		}
	}
	
}
public class Main {

	public static void main(String[] args) {
		Comparator<Tv> com=new Comparator<Tv>() {

			@Override
			 public int compare(Tv p1,Tv p2){
                if(p1.end!=p2.end)//先按照节目结束时间排序
                {
                    return p1.end-p2.end;
                }
                else//若结束时间相同,则按照开始时间排序
                {
                    return p1.start-p2.start;
                }

                }

			
		};
		Scanner cin=new Scanner(System.in);
		
		while(cin.hasNext()) {
			int m=cin.nextInt();//节目数
			if(m==0) {
				break;
			}
			ArrayList<Tv> list=new ArrayList<Tv>();
			for(int i=0;i<m;i++) {
				int start=cin.nextInt();
				int end=cin.nextInt();
				Tv tv=new Tv(start,end);
				list.add(tv);//将对象存入数组中
			}
			Collections.sort(list,com);
			int j=0;
			int count=1;//计数
			for(int i=1;i<m;i++) {
				if(list.get(i).start>=list.get(j).end) {
	
					j=i;
					count++;
				}
			}
			System.out.println(count);
		}
		

	}

}

最小生成树(Kruskal)

题目描述

编程实现Kruskal算法,求图的最小生成树(MST)的权重。

输入

每组数据分为两个部分,第一部分为图的点数n,和边数m,
第二部分为m行,每一行输入三个数字,前两个为两个顶点的编号,第三个为边权重。

输出

最小生成树的权重。

样例输入 Copy

3 3
0 1 10
0 2 15
1 2 50

样例输出 Copy

25

思路

并查集+排序

代码

import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
class edge{
    int x,y;//点
    int w;//边
};
//排序
class cmp implements Comparator
{
    public int compare(edge a, edge b) {
        if(a.wrank[y]) {
             pa[y]=x;
         }else {
             pa[x]=y;
             if(rank[x]==rank[y]) {
                 rank[y]++;
             }
         }
         sum+=w;
         return 1;
    }
  
    public static void main(String[] args) {
  
        Scanner cin = new Scanner(System.in);
        //while(cin.hasNext()) {
        edge e[]=new edge[1000];//存边与边之间的信息 
        int n=cin.nextInt();//图的点
        int m=cin.nextInt();//边数
        for(int i=0;i

牛牛的蛋糕

题目描述

众所周知,牛妹非常喜欢吃蛋糕。

第一天牛妹吃掉蛋糕总数三分之一多一个,第二天又将剩下的蛋糕吃掉三分之一多一个,以后每天吃掉前一天剩下的三分之一多一个,到第n天准备吃的时候只剩下一个蛋糕。

牛妹想知道第一天开始吃的时候蛋糕一共有多少呢?

输入

输入n,0

输出

输出第一天蛋糕的数量。

样例输入 Copy

2
4

样例输出 Copy

3
10

思路:

dp,首先先将dp数组的第一行和第一列初始化

代码:

import java.util.Scanner;
 
public class Main {
     
    public static void main(String[] args) {
  
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext()) {
      int  n=cin.nextInt();
      int m=cin.nextInt();
      int map[][]=new int[n+1][m+1];
      int dp[][]=new int[n+1][m+1];
      for(int i=1;i<=n;i++) {
          for(int j=1;j<=m;j++) {
              map[i][j]=cin.nextInt();
          }
      }
      /*for(int i=1;i<=n;i++) {
          for(int j=1;j<=m;j++) {
              System.out.print(map[i][j]+" ");
          }
          System.out.println();
      }*/
      dp[1][1]=map[1][1];
      for(int i=2;i<=m;i++) {dp[1][i]=map[1][i]+dp[1][i-1];}
      for(int j=2;j<=n;j++) {dp[j][1]=map[j][1]+dp[j-1][1];}
    /* for(int i=1;i<=n;i++) {
          for(int j=1;j<=m;j++) {
              System.out.print(dp[i][j]+" ");
              }
          System.out.println();
      }*/
      for(int i=2;i<=n;i++) {
          for(int j=2;j<=m;j++) {
              dp[i][j]=Math.min(dp[i-1][j-1], Math.min(dp[i][j-1], dp[i-1][j]))+map[i][j];
          }
      }
      System.out.println(dp[n][m]);
          
     
        }
    }
}

尼科彻斯定理

时间限制: 1 Sec 内存限制: 128 MB

提交: 0 解决: 0 admin

提交状态讨论版

题目描述

验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。

例如:

1^3=1

2^3=3+5

3^3=7+9+11

4^3=13+15+17+19

输入

多组输入,输入一个整数。

输出

输出分解后的字符串。

样例输入 Copy

6

样例输出 Copy

31+33+35+37+39+41

代码:

import java.util.Scanner;
 
public class Main {
    static void print_(int m,int i,boolean flag){
        if(flag==true){
            for(int k=0;k<m;k++){
                System.out.print(i+2*k);
             
              if(k<m-1) System.out.print("+");
            }
        }
        else System.out.print("-1");
         
    }
 
    public static void solve(int m) {
        boolean flag=false;
        int sum0=m*m*m;
        int sum1=0,start;
        for(int i=1;i<=sum0;i+=2){
            
            sum1=0;
            start=i;
            for(int j=0;j<m;j++){
              sum1=sum1+start;
              start+=2;
            }
            if(sum1==sum0) {
                flag=true;
                print_(m,i,flag);
                return;
            }
        }
         
        flag=false;
        print_(m,0,false);
 
 
    }
    public static void main(String[] args) {
  
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext()) {
      int  n=cin.nextInt();
       
    
     solve(n);
     System.out.println();
     
        }
    }
}

DNA序列

时间限制: 1 Sec 内存限制: 128 MB

提交: 0 解决: 0 admin

提交状态讨论版

题目描述

一个DNA序列由A/C/G/T四个字母的排列组合组成。G和C的比例(定义为GC-Ratio)是序列中G和C两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工程中,这个比例非常重要。因为高的GC-Ratio可能是基因的起始点。

给定一个很长的DNA序列,以及要求的最小子序列长度,研究人员经常会需要在其中找出GC-Ratio最高的子序列。

输入

输入一个字符串型基因序列和整型子串的长度。

输出

找出GC比例最高的子串,如果有多个输出第一个的子串。

样例输入 Copy

AACTGTGCACGACCTGA
5

样例输出 Copy

GCACG

提示

字符串长度<=100000

思路:

两重循环,第二层用于确定cg的数量以及下标,同时用index记录最大的那个cg的下标

代码:



import java.util.Scanner;
 
public class Main {
     public static int solve(String str,int n) {
         int i,j;
         int count;
         int max=0;
         int index=0;
         for(i=0;i+n<str.length();i++) {
             count=0;
             for(j=0;j<n;j++) {
                 if(str.charAt(i+j)=='G'||str.charAt(i+j)=='C')
                     count++;
                 
             }
             if(count>max) {
                 max=count;
                 index=i;
             }
              
         }
         return index;
     }
    public static void main(String[] args) {
  
        Scanner cin = new Scanner(System.in);
        while(cin.hasNext()) {
            int start;
       String str=cin.next();
      int  n=cin.nextInt();
     if(str.length()==0||n<=0||n>str.length()) {
         return ;
     }else {
         start=solve(str,n);
         for(int i=0;i<n;i++) {
             System.out.print(str.charAt(start+i));
         }
     }
        }
    }
}
 

问题 F: 隔离14天

时间限制: 1 Sec 内存限制: 128 MB

提交: 636 解决: 105 201501010119

提交状态讨论版

题目描述

如果实施更为严格的防控措施,一辆汽车上有一个确诊患者或者密切接触者,那么该汽车上所有的人都被认为是密切接触者,全部需要自行居家隔离或者集中隔离14天。
现在假定编号为0的乘客冠状病毒核酸检验呈阳性,请编写一个程序统计需隔离的总人数(包括编号为0的乘客)。

输入

第1行的第1个数字n表示总人数,第2个数字m表示汽车数量;从第2行开始,接下来的m行表示每辆汽车的司乘人员总人数和人员编号(人员编号是一个固定值,可以对应于我们的身份证号码),每一行的第1个数字k表示该汽车的司乘人员总数,接下来的k个数字表示每一个人的编号。

输出

需要被隔离的总人数。

样例输入 Copy

100 4
2 1 2
5 10 13 11 12 14
2 0 1
2 99 2

样例输出 Copy

4

思路:

并查集,然后用cout记录要隔离的人数,在find_set(i)中寻找根节点为0的,找到就count++;

代码:

import java.util.Scanner;
  
 
public class Main {
    static int pa[]=new int[1000];
    static int rank[]=new int[1000];
    public static void make_set(int x) {
        pa[x]=x;
    }//初始化
    public static int find_set(int x) {
        if(x!=pa[x]) {
             pa[x]=find_set(pa[x]);
        }
        return pa[x];
    }//查找
    public static  void union_set(int x,int y) {
        x=find_set(x);
        y=find_set(y);
        if(x<y)pa[y]=x;
        else pa[x]=y;
    }//按秩合并x,y所在的集合
     public static void main(String[] args) {
         Scanner cin = new Scanner(System.in);
         int n=cin.nextInt();
         int m=cin.nextInt();//车辆
         int head=0;
         int x=0;
         for(int i=1;i<=n;i++) {make_set(i);}
         for (int i=1;i<=m;i++)
         {
            int k=cin.nextInt();
             if (k>=1) head=cin.nextInt();
             for (int j=2;j<=k;j++)
             {
                 x=cin.nextInt();
                 union_set(x,head);//连接
             }
         }
         int count=0;
         for(int i=0;i<n;i++) {
             if(find_set(i)==0)count++;
         }
         System.out.println(count);
       
     }
}

问题 H: 单源最短路径问题

时间限制: 1 Sec 内存限制: 128 MB

提交: 228 解决: 122 201501010119

提交状态讨论版

题目描述

编程实现Dijkstra算法,求一个有向加权图中,从源点出发到其他各个顶点的最短路径。

输入

第1行第1个值表示顶点个数,第2个值表示边个数;第2行开始为边(两个顶点,边的起点和终点)及权重。

输出

顶点0到每一个顶点的最短路径长度。

样例输入 Copy

5 7
0 1 10
0 3 30
0 4 100
1 2 50
2 4 10
3 2 20
3 4 60

样例输出 Copy

0 10 50 30 60

代码:
import java.util.Scanner;
  
public class Main {
     public static void main(String[] args) {
         Scanner cin = new Scanner(System.in);
        int[][] graph=new int[1000][1000];
         
        int d=cin.nextInt();//dian
        int b=cin.nextInt();//bian
        int[] dis=new int[d];
        boolean[] visited=new boolean[d];
        for(int i=0;i<d;i++) {
            visited[i]=false;
        }
        visited[0]=true;
        for(int i=0;i<d;i++) {
            for(int j=0;j<d;j++) {
                graph[i][j]=99999;
            }
        }
         
        for(int i=1;i<=b;i++) {
            int x=cin.nextInt();
            int y=cin.nextInt();
            graph[x][y]=cin.nextInt();
            graph[y][x]=graph[x][y];
              
        }
      for(int i=0;i<d;i++) {
            graph[i][i]=0;
        }
          
     
          
          
          
       dijkstra(graph, visited, dis,d);
        for(int i=0;i<dis.length;i++)
            System.out.print(dis[i]+" ");
          
         
    }
     static int maxint=99999;
     public static void dijkstra(int map[][],boolean used[],int dis[],int n){
          
         for(int i=0;i<n;i++) //初始化距离数组
             dis[i] = map[0][i]; 
  
         int k=0;
         for(int i=1;i<n;i++){
             int tmin = maxint;
             //找出未访问点中距离值最小的点k,标记其为访问过
             for(int j=1;j<n;j++)
                 if( !used[j] && dis[j] < tmin){
                       tmin = dis[j];
                       k = j;    
                  } 
             used[k] = true;
             for(int j=1;j<n;j++)
                 //对找出的点的相邻边进行松弛操作
                 if(!used[j]&&(dis[k] + map[k][j] < dis[j])) 
                     dis[j] = dis[k] + map[k][j];
         }
    }
  
       
     
      
   
  
       
       
      
}

你可能感兴趣的:(算法题)