算法設計與分析 遞歸與分治 回溯算法 分支限界 動態規劃 貪心算法 近擬算法

<!-- /* Font Definitions */ @font-face {font-family:宋體; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋體"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋體; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:1581209740; mso-list-type:hybrid; mso-list-template-ids:1166155990 -1205154132 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 {mso-level-number-format:japanese-counting; mso-level-text:%1.; mso-level-tab-stop:27.0pt; mso-level-number-position:left; margin-left:27.0pt; text-indent:-27.0pt;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->

經典的算法問題:

(拿出來供自己和大家都看看吧,算法學習不能停。)

一.    遞歸與分冶算法。

題目:棋盤履蓋 (javascript)

<HTML>

  <HEAD>

  <TITLE> 棋盤履蓋 </TITLE>

</HEAD>

  <Script Language="JavaScript">

              function getRandColor(){ 

               return '#'+(Math.random()*0xffffff<<0).toString(16); 

    } 

       document.write("<BODY bgcolor=" +  getRandColor() +">")

       document.write("<h1><center><font color =red> 棋盤履蓋 </font></center></h1>");

       var tile=0;

       var t = 0;

 

  //new 個數組

  </Script>

        <Script Language="JavaScript">

             var k = prompt(" 輸入棋盤的規格 /n2<sup>k</sup>","2");

        var row = Math.pow(2,k);

        var col = row;

             alert(" 行數 " + row +" 列數 " + col);

             var board = new Array(row);

             for(i = 0; i<row; i++) {

                    board[i] = new Array(col);

                    for(j = 0; j<col; j++) {

                           board[i][j] = 0;

                    }

             }

             var drow = prompt(" 輸入特殊方格所在的行 ","0");

             var dcol = prompt(" 輸入特殊方格所在的列 ","0");

             alert("chessBoard begin");

        

           var tile = 0;

       function chessBoard(tr,tc,dr,dc,size) {

       if(size == 1) {

       }

       else {

              var t = getRandColor() + "," + (++tile);

              //var t=++tile;

              var s= size/2;

              // 覆蓋左上角子棋盤

              if(dr<tr+s && dc<tc+s) {

                     chessBoard(tr,tc,dr,dc,s);

              }

              else {

                     board[tr+s-1][tc+s-1] = t;

                     chessBoard(tr,tc,tr+s-1,tc+s-1,s);

              }

             

              // 覆蓋右上角棋盤

              if(dr<tr+s && dc>=tc+s) {

                     chessBoard(tr,tc+s,dr,dc,s);

              }

              else {

                     board[tr+s-1][tc+s] = t;

                     chessBoard(tr,tc+s,tr+s-1,tc+s,s);

              }

             

              // 覆蓋左下角棋盤

              if(dr>=tr+s && dc<tc+s) {

                     chessBoard(tr+s,tc,dr,dc,s);

              }

              else {

                     board[tr+s][tc+s-1] = t;

                     chessBoard(tr+s,tc,tr+s,tc+s-1,s);

              }

             

              // 覆蓋右下角棋盤

              if(dr>=tr+s && dc>=tc+s) {

                     chessBoard(tr+s,tc+s,dr,dc,s);

              }

              else {

                     board[tr+s][tc+s] = t;

                     chessBoard(tr+s,tc+s,tr+s,tc+s,s);

              }

       }

                     }

            

             chessBoard(0,0,drow,dcol,col);

             board[drow][dcol] ="#ffffff" +",0";

             </Script>

             <table align = "center"  border="0">

                   

             <Script Language = "JavaScript">

             for(i = 0; i<row;i++) {

             document.write("<tr>");

             for(j = 0 ;j<col;j++) {

                    var paraArr = board[i][j].split(",");

                    document.write("<td width=30 height=20 bgcolor=" + paraArr[0] +">" + paraArr[1] +" </td>");

             }

             document.write("</tr>");

      }

     

 

      </Script>

  </table>

  </BODY>

  </HTML>

格雷碼:( java

import java.util.Scanner;

class Gray {

       private static byte[][] ngray;

       private static int num;                                       // 輸出總行數

       private int ng;

       private static int loops;

       public Gray(int n) {

              this.ng = n;

              num = (int)Math.pow(2,n);

              ngray = new byte[num+1][n+1];

              loops = 1;

              findGrays(ng);

       }

      

       public static void findGrays(int n) {

              if(n<1) return;

                     handleArray(n,(int)Math.pow(2,n));

                     findGrays(n-1);

}

 

       private void printGrays() {

              for(int i = 1; i<=num; i++) {

                     for(int j = 1; j<=ng;j++) {

                            System.out.print(ngray[i][j] + "/t");

                     }

                     System.out.println();

              }

       }

      

       private static void handleArray(int n,int lo) {

              int i;

              // 定義一個用於處理, 0 1 次序的變量。

              boolean zoFlag = true;

             

              int loopnum = num/lo;                                                     // 定義一個用於控制可以循環的次數的變量

             

              for(i = 1;i<=loopnum;++i) {

                            for(int j =1;j<=lo/2;j++) {

                                   ngray[(i-1)*lo+j][n] = (byte)(zoFlag?0:1);//01 標誌爲 true ,返回 0 ,否則 1

                            }

                            for(int j = lo/2+1;j<=lo;j++) {

                                          ngray[(i-1)*lo+j][n] = (byte)(zoFlag?1:0);//01 標誌爲 true ,返回 1 ,否則 0

                            }

                     zoFlag = zoFlag?false:true;

              }

       }

      

       public static void main(String args[]) {

              Scanner sc = new Scanner(System.in);

              System.out.println(" 輸入格雷碼的位數 ");

              int graynum = sc.nextInt();

              Gray gray = new Gray(graynum);

              gray.printGrays();

       }

}

二.    回溯算法。

簡單 0-1 揹包問題 java

import java.util.Scanner;

 

 

public class BeiBao {

       double[] price ;

       double[] weight;

       int n ;

       double c ;

       double bestprice = 0;

       double currentweight = 0;

       double currentprice = 0;

      

       public void input() {

              Scanner sc = new Scanner(System.in);

             

             

              String inf = sc.nextLine();

              String[] arr = inf.split(" ");

              n = Integer.parseInt(arr[0]);

              c = Double.parseDouble(arr[1]);

              while (n != 0 && c != 0) {

                     weight = new double[n];

                     price = new double[n];

                     // 得到 weight

                     inf = sc.nextLine();

                     arr = inf.split(" ");

                     for (int loop = 0; loop < n; loop++) {

                            weight[loop] = Double.parseDouble(arr[loop]);

                     }

                     // 得到 price

                     inf = sc.nextLine();

                     arr = inf.split(" ");

                     for (int loop = 0; loop < n; loop++) {

                            price[loop] = Double.parseDouble(arr[loop]);

                     }

                     inf = sc.nextLine();

                     arr = inf.split(" ");

                    

                     //print();

                     backtrack(0);

                     System.out.println((int)bestprice);

                    

                     currentweight = currentprice = 0.0;

                     bestprice = 0.0;

                     n = Integer.parseInt(arr[0]);

                     c = Double.parseDouble(arr[1]);

              }

              sc.close();

       }

      

       public void backtrack(int i) {

              if(i>=n) {

                     if(currentprice > bestprice) {

                            bestprice = currentprice;

                     }

                     return;

              }

             

              if(currentweight + weight[i] <=c ) {

                     currentweight += weight[i];

                     currentprice += price[i];

                     backtrack(i+1);

                     currentweight -= weight[i];

                     currentprice -= price[i];

              }

              if(currentprice + bound(i+1) > bestprice) {

                     backtrack(i+1);

              }

       }

      

       double bound(int i) {

              double sum = 0.0;

              for(int j = i; j<n; j++) {

                     sum += price[j];

              }

              return sum;

       }

      

       void print() {

              System.out.println("n" + n + "c" + c);

              for(int i = 0;i<weight.length;i++) {

                     System.out.println(weight[i] + "  " + price[i]);

              }

       }

      

       public static void main(String args[]) {

              BeiBao bb = new BeiBao();

              bb.input();

              //System.out.println(bb.bestprice);

       }

      

 

}

八皇后問題 java

class EtQueen {

      

       int n ;

       int x[];

       int qnum = 1;

      

       public static void main(String args[]) {

              new EtQueen(8);

       }

      

       EtQueen (int n) {

              this.n = n;

              x = new int[n+1];

              backtrack(1);

       }

      

       void backtrack(int i) {

              if(i>n) {

                     printQueens();

                     qnum ++;

              }

             

              for(int j = 1; j<=n; ++j)  {

                     if(cangoon(i,j)) {           // 符合繼續進行的條件

                            x[i] = j;

                            backtrack(i+1);

                            x[i] = 0;

                     }

              }

       }

      

       boolean cangoon(int i,int j) {

              for(int k = 1; k<i; k++ ) {

                     if(x[k] == j || Math.abs(i-k) == Math.abs(x[k]-j) ) {

                            return false;

                     }

              }

              return true;

       }

      

       void printQueens () {

              System.out.println("No " + qnum + ":");

              for(int i = 1; i<=n; i++) {

                     for(int j = 1; j<=n; j++)  {

                            if(x[i] == j) {

                                   System.out.print('A');

                            }else {

                                   System.out.print('.');

                            }

                     }

                     System.out.println();

              }

       }

}

最優裝載問題 (java)

import java.util.Scanner;

 

class Zyzz {

       int c1 ,c2 ,n ;

       int[] weight;;

       int bestweight ;

       int currentweight ;

       int r ,totalweight;

       public static void main(String args[]) {

              new Zyzz().input();

       }

      

       public void input() {

              Scanner sc = new Scanner(System.in);

              String inf;

              String[] temp;

             

              while(true) {

                     currentweight  = bestweight = r =0;

                  inf = sc.nextLine();

                     temp = inf.split(" ");

                     int a,b;

                     a = Integer.parseInt(temp[0]);

                     b = Integer.parseInt(temp[1]);

                     n = Integer.parseInt(temp[2]);

                     if(a == 0 && b ==0 && n == 0) break;

                     if(a<b) {

                            c1 = a;

                            c2 = b;

                     }else {

                            c2 = a;

                            c1 = b;

                     }

                     weight = new int[n];

                     inf = sc.nextLine();

                     temp = inf.split(" ");

                     for(int i = 0; i<n; i++) {

                            weight[i] = Integer.parseInt(temp[i]);

                            r+=weight[i];

                            totalweight = r;

                     }

                     bestLoad();

                     if(totalweight - bestweight > c2) {

                            System.out.println("No");

                     }else {

                            System.out.println("Yes");

                     }

             

              }

              sc.close();

       }

      

       void bestLoad() {

              backtrack(0);

              //System.out.println("bestload = " + bestweight  + "r = " +r);

       }

      

       public void backtrack(int i) {

              if(i>=n) {

                     bestweight = currentweight ;

                     //System.out.println("bestweight = " + bestweight  + "r = " +r);

                     return;

              }

             

              if(currentweight + weight[i] <=c1 ) {

                     r-=weight[i];

                     currentweight += weight[i];

                     //System.out.println("i " + i +"currentweight = " + currentweight  + "r = " +r );

                     backtrack(i+1);

                     currentweight -= weight[i];

                     r+=weight[i];

              }

             

              r-=weight[i] ;

              if(currentweight + r> bestweight) {

                     backtrack(i+1);

              }

              r+=weight[i];

       }

}

 

 

三.    分支限界算法。

迷宮問題 (java)

import java.util.Scanner;

 

public class MiGong {

       static char[][] maze;

       static boolean[][] isVisited;

       static int posStartX ;

       static int posStartY ;

       static int posEndX ;

       static int posEndY ;

      

       static int n = 12;// 迷宮的規模

      

       // 先進先出對列

       static Queue queue = new Queue();

       static Element ende ;

       static Element starte;

       MiGong() {

              maze = new char[n][n];

              isVisited = new boolean[n][n];

              Scanner sc = new Scanner(System.in);

              // 初始化老鼠的位置和迷宮出口

              String inf = "";

              inf = sc.nextLine();

              String[] posStr = inf.split(" ");

              posStartX = Integer.parseInt(posStr[0])-1;

              posStartY = Integer.parseInt(posStr[1])-1;

              posEndX = Integer.parseInt(posStr[2])-1;

              posEndY = Integer.parseInt(posStr[3])-1;

             

              ende = new Element(posEndX,posEndY,0,null);

              starte = new Element(posStartX,posStartY,0,null);

             

              for(int i=0;i<n;i++) {

                     inf = sc.nextLine().trim();

                     for(int j = 0;j<n;j++) {

                            maze[i][j] = inf.charAt(j);

                     }

              }

              sc.close();

              System.out.println(" 打印迷宮 ");

              for(int i = 0;i<n;i++) {

                     for(int j = 0;j<n;j++) {

                            System.out.print(maze[i][j]);

                            isVisited[i][j] = false;

                     }

                     System.out.println();

              }

       }

      

       private static class Element {

              Element(int x,int y,int num,Element pre) {

                     this.x = x;

                     this.y = y;

                     this.num = num;

                     this.pre = pre;

              }

              int x;

              int y;

              Element pre;

              int num;// 步數

             

              boolean equals(Element e) {

                     if(e==null) return false;

                     if(x == e.x && y == e.y) {

                            return true;

                     }

                     return false;

              }

             

              void print() {

                     System.out.println(" 位置 " + "X=" + x + "Y=" + y + " Num=" + num);

              }

       }

      

       public static void bbTSP() {

              isVisited[posStartX][posStartY] = true;

              queue.enq(starte);

              queue.enq(null);

              do{

                     Element curE = (Element)queue.deq();

                     while(curE != null) {

                            addElementToQueue(curE);

                            curE = (Element)queue.deq();

                            if(ende.equals(curE)) {

                                   ende = curE;

                                   return ;

                            }

                     }

                     queue.enq(null);

              }while(!queue.empty());

       }

       private static void addElementToQueue(Element e) {

 

              // 對上下左右進行處理 , 沒超出邊界且不是障礙物時 , 加入隊列

              // 向左走

              if(e.y-1>=0 && maze[e.x][e.y-1] != 'X' && !isVisited[e.x][e.y-1]) {

                     Element e1 =new Element(e.x,e.y-1,e.num+1,e);

                     queue.enq(e1);

                     isVisited[e.x][e.y-1] = true;

                     e1.print();

              }

             

              // 向右走

              if(e.y+1 <n && maze[e.x][e.y+1] != 'X' &&!isVisited[e.x][e.y+1]) {

                     Element e1 =new Element(e.x,e.y+1,e.num+1,e);

                     queue.enq(e1);

                     isVisited[e.x][e.y+1] = true;

                     e1.print();

              }

             

              // 向上走

              if(e.x-1 >0 && maze[e.x-1][e.y] != 'X' && !isVisited[e.x-1][e.y]) {

                     Element e1 =new Element(e.x-1,e.y,e.num+1,e);

                     queue.enq(e1);

                     isVisited[e.x-1][e.y] = true;

                     e1.print();

              }

             

              // 向下走

              if(e.x+1 <n && maze[e.x+1][e.y] != 'X' && !isVisited[e.x+1][e.y]) {

                     Element e1 =new Element(e.x+1,e.y,e.num+1,e);

                     queue.enq(e1);

                     isVisited[e.x+1][e.y] = true;

                     e1.print();

              }

       }

      

       public static void main(String args[]) {

              new MiGong();

              bbTSP();

              System.out.println(ende.num);

       }

      

}

 

// 下面建一個 Queue

class Queue extends java.util.Vector {

       public Queue() {

              super();

       }

 

       public synchronized void enq(Object x) {

              super.addElement(x);

       }

 

       public synchronized Object deq() {

              /* 隊列若爲空,引發 EmptyQueueException 異常 */

              if (this.empty())

                     throw new EmptyQueueException();

              Object x = super.elementAt(0);

              super.removeElementAt(0);

              return x;

       }

 

       public synchronized Object front() {

              if (this.empty())

                     throw new EmptyQueueException();

              return super.elementAt(0);

       }

 

       public boolean empty() {

              return super.isEmpty();

       }

 

       public synchronized void clear() {

              super.removeAllElements();

       }

 

       public int search(Object x) {

              return super.indexOf(x);

       }

}

 

       class EmptyQueueException extends java.lang.RuntimeException {

       public EmptyQueueException() {

              super();

       }

}

 

四.    動態規劃算法。

多邊形問題:( java

import java.util.Scanner;

import java.util.StringTokenizer;

 

 

public class PolygonGame {

       int[] v;

       char[] op;

       int arr[][][];

       int n ;

       int minf,maxf;

      

       void input() {

              Scanner sc = new Scanner(System.in);

              n = sc.nextInt();

             

              arr = new int[n+1][n+1][2];

              v = new int[n+1];

              op = new char[n+1];

             

              sc.nextLine();

              String inf = sc.nextLine();

              sc.close();

              StringTokenizer st = new StringTokenizer(inf);

              for(int i = n;i>=1; i--) {

                     v[i] = Integer.parseInt(st.nextToken());

                     op[i] = st.nextToken().charAt(0);

              }

             

              for(int i = 1; i<=n; i++) {

                     arr[i][1][0] = arr[i][1][1] = v[i];

              }

       }

      

      

       void minMax(int i,int s,int j) {

              int a = arr[i][s][0];

              int b = arr[i][s][1];

              int r = (i+s-1)%n+1;

              int c = arr[r][j-s][0];

              int d = arr[r][j-s][1];

             

              if(op[r] == '+') {// 當運算符爲加時

                     minf = a + c;

                     maxf = b + d;

              }

              else {                      // 當運算符爲乘時

                     int[]e = new int[5];

                     e[1] = a * c;

                     e[2] = a * d;

                     e[3] = b * c;

                     e[4] = b * d;

                     minf = Math.min(Math.min(e[1],e[2]),Math.min(e[3],e[4]));

                     maxf = Math.max(Math.max(e[1],e[2]),Math.max(e[3],e[4]));

              }

       }

      

       int polyMax() {

              for(int j = 2;j<=n;j++) {                                                         // 鏈的結束位置

                     for(int i = 1;i<=n;i++) {                                                  // 鏈的起始位置

                            for(int s = 1;s<j; s++) {                                           // 把一條鏈斷開的位置有 j-1 種情況,因爲第一步斷開了一條邊

                                   minMax(i,s,j);

                                   if(arr[i][j][0] > minf) arr[i][j][0] = minf;      // 更新值操作

                                   if(arr[i][j][1] < maxf) arr[i][j][1] = maxf;

                            }

                     }

              }

             

              int temp = 0;                                                                                // 求出從不同伴置斷開的最大值勤

              for(int i = 1; i<= n; i++) {

                     if(temp < arr[i][n][1]) temp = arr[i][n][1];

              }

              System.out.println(temp);

              return temp;

       }

      

       public static void main(String args[]) {

              PolygonGame pg = new PolygonGame();

              pg.input();

              pg.polyMax();

       }

}

 

 

五.    貪心算法。

Dijkstra- 單源最短路徑(java)

import java.util.Scanner;

 

 

public class Dijkstra {

       private static int n ;

       private static int[][] route;            // 路徑長度

      

       private static int[] res;                  // 最終結果

       private static boolean[] hasDone;          // 已解決的問題序列

       private static boolean[] notDone;          // 未解決的問題序列

      

       /* 利用 Dijkstra 算法求解從頂點號 0 到其它頂點的最短路徑

         * 最終結果保存在了 res 數組序列中

         */

       public Dijkstra() {

              try {

              Scanner sc = new Scanner(System.in);

              // 初始化問題的規模     

              n = sc.nextInt();

              route = new int[n][n];

              res = new int[n];

              hasDone = new boolean[n];

              notDone = new boolean[n];

              notDone[0] = false;

              hasDone[0] = true;

             

              sc.nextLine();

              String inf = "";

              String[] dataArr;

              for(int i = 0;i<n;i++) {

                     inf = sc.nextLine();

                     dataArr = inf.split(" ");

                     for(int j = 0;j<n;j++) {

                            route[i][j] = Integer.parseInt(dataArr[j]);

                     }

              }

              /*System.out.println(" 問題規模 " + n    );

              for(int i = 0;i<n;i++) {

                     for(int j = 0;j<n;j++) {

                            System.out.print(route[i][j] + "/t");

                     }

                     System.out.println();

              }*/

              for(int i = 1; i<n;i++) {

                     res[i] = route[0][i];

                     notDone[i] = true;

                     hasDone[i] = false;

              }

              sc.close();

              }catch(Exception e) {

                    

              }

             

       }

      

       public static void dijkstra() {

       //     System.out.println(" 進行求解 ");

       //     printMinRoute();

              int i = 1;                // 問題求解完成數 ( 一共要完成 n )

              //int minN = 0;              // 當前要處理的頂點

              while(i<n) {           // 只要還沒有處理完 n 個數據

                     update(getMinRoute());

       //            printMinRoute();

                     i++;

              }

       //     printMinRoute();

              for(i =1;i<n-1;i++) {

                     System.out.print(res[i] + " ");

              }

              System.out.println(res[n-1]);

       }

      

       private static int getMinRoute() {

              int minN = -1;

              int temp = Integer.MAX_VALUE;

              for(int i = 1; i< n; ++i) {

                     /*for(int t =1;t<n;t++) {

                            System.out.print(res[t] + " ");

                     }

                     System.out.println()*/;

                     if(notDone[i] == true && res[i] > 0 ) {

                            if(temp > res[i]) {

                                   temp = res[i];

                                       minN = i;

                            }

                     }

              }

             

              return minN;

       }

      

       /* 輸出最後結果

         *

         */

       public static void printMinRoute() {

              System.out.println(" 打印結果 ");

              for(int i = 1; i<n ;i++) {

                     System.out.println(" 到第 " + i + " 個頂點的最小路徑爲 " + res[i]);

              }

       }

      

       /*

         * 對由於加入頂點 i 而引起的數據變化 , 進行更新操作

         */

       private static void update(int i) {

              // 結果序列進行更新

              for(int k = 1 ; k< n ; k++) {

                     if(i!=k && notDone[k] == true && route[i][k]>0) {

                            if(route[i][k] + res[i] < res[k] || res[k] <0) {

                                   res[k] = route[i][k] + res[i];

                            }

                     }

              }

              hasDone[i] = true; 

              // 從未解決序列中刪除

              notDone[i] = false;

       }

      

       public static void main(String args[])    {

              Dijkstra ds = new Dijkstra();

              dijkstra();

       }

}

六.    近似算法。

具有三角不等式特點的旅行售貨員問題(C).

#include <stdio.h>

 

//#define _DEBUG

#undef _DEBUG

// 定義最大值宏

#define M 9999

// 定義規模

#define SIZE 25

// 定義初始化數據

#define INIT -1

// 定義一個 25*25 的二維數組

int arr[SIZE][SIZE];

// 最小消費向量

// 最小集

int closest[SIZE];

// 訪問標誌數組

int lowcost[SIZE];

bool visited[SIZE];

// 加入頂點的順序

int addorder[SIZE];

// 初始化操作

void init()

{

       int i,j;

       for(i=0;i<SIZE;++i)

       {

              for(j=0;j<SIZE;++j)

              {

                     arr[i][j] = M;

              }

              lowcost[i] = INIT;

              closest[i] = INIT;

              visited[i] = false;

              addorder[i] = INIT;

       }

}

 

// 輸出矩陣

void printArray(int num)

{

       int i,j;

       for(i=1;i<=num;++i)

       {

              for(j=1;j<=num;++j)

              {

                     printf("%d/t",arr[i][j]);

              }

              printf("/n");

       }

}

 

// 輸出最小生成樹

void printMin(int num)

{

#ifdef _DEBUG

       printf(" 最小生成樹 /n");

       printf("4 的值 %d %d/n",closest[4],lowcost[4]);

#endif

       int i;

       for(i=1;i<num;i++)

       {

              printf("%d %d/n",closest[addorder[i]],addorder[i]);

       }

}

 

//prime 算法

void prime(int num)

{

       // 第一個頂點初始化

       visited[1] = true;

       // 初始化最小消費和最小集合

       for(int i = 2;i<=num;i++)

       {

              lowcost[i] = arr[1][i];

              closest[i] = 1;

              visited[i]  = false;

       }

       //num-1 次循環完後 , 解決問題 .

       for(i = 1;i<num;i++)

       {

              int min = M;

              int j = 1;

              for(int k = 2;k<=num;k++)

              {

                     if((lowcost[k]<min) && (!visited[k]))

                     {

                            min = lowcost[k];

                            j = k;

                     }

              }

 

      

              visited[j] = true;

              addorder[i] = j;

 

#ifdef _DEBUG

              printf(" %d 次加入了頂點 %d/n",i,j);

#endif

             

              for(k = 1;k<=num;k++)

              {

                     if((arr[j][k]<lowcost[k]) && (!visited[k]))

                     {

                            lowcost[k] = arr[j][k];

                            closest[k] = j;

                     }

              }

#ifdef _DEBUG

              printMin(num);

#endif

       }

}

 

// 前序遍歷輸出結果

void printMinValue(int num)

{

       int verarr[SIZE];

       // 開始頂點 1

       verarr[1] = 1;

       bool s[SIZE][SIZE];

       int j,k;

       for(j=1;j<=num;++j)

       {

              for(k=1;k<=num;++k)

              {

                     s[j][k] = false;

              }

       }

       bool findflag = false;

       int i = 1;

       // 定義一個 verarr 向量位置的變量,同時可做爲結束循環的標誌。

       int verpos = 1;

       // 進行 num-2 次循環

       while(i>0)

       {

              // 重置 findflag;

              findflag = false;

              // addorder verarr[i-1] 的第一個鄰接頂點

              for(j=1;j<num;++j)

              {

                     if(closest[addorder[j]] == verarr[i] && !s[verarr[i]][addorder[j]])

                     {

                            s[verarr[i]][addorder[verpos]] = true;

                            verarr[++verpos] = addorder[j];

                            findflag = true;

                            ++i;

                            break;

                     }

              }

//            printf("i 的值 %d/n",i);

              if(verpos == num)

                     break;

              if(!findflag)

              {

                     i--;

              }

       }

 

       int sum = 0;

 

       for(k=1;k<num;k++)

       {

#ifdef _DEBUG

              printf("%d/t",verarr[k]);

              printf("%d/t %d/t %d/n",verarr[k],verarr[k+1],arr[verarr[k]][verarr[k+1]]);

#endif

              sum = sum + arr[verarr[k]][verarr[k+1]];

       }

       sum += arr[verarr[k]][1];

       printf("%d/n",sum);

 

      

 

}

 

// 主方法

int main()

{

#ifdef _DEBUG

       printf(" 調試模式 /n");

#endif

       // 執行初始化操作

       init();

       // 頂點數和邊數

       int vertex_num,edge_num;

       // 輸入頂點數

       scanf("%d",&vertex_num);

       // 輸入邊數

       scanf("%d",&edge_num);

       // 輸入值

       int loop;

       // 矩陣從索引 1 開始

       for(loop = 1;loop<=edge_num;++loop)

       {

              int tmpver1,tmpver2,tmpedg;

              scanf("%d%d%d",&tmpver1,&tmpver2,&tmpedg);

 

              // 存入矩陣 ( 記住是無向圖 )

              arr[tmpver1][tmpver2] = tmpedg;

              arr[tmpver2][tmpver1] = tmpedg;

       }

       prime(vertex_num);

 

#ifdef _DEBUG

       printArray(vertex_num);

#endif

//     printMin(vertex_num);

       printMinValue(vertex_num);

       return 0;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章