1. 程式人生 > >騰訊秋招web後臺方向筆試題第二題,尋找重要城市,dfs解法。

騰訊秋招web後臺方向筆試題第二題,尋找重要城市,dfs解法。

問題描述:

      小Q所在的王國有n個城市,城市之間有m條單向道路連線起來。對於一個城市v,從城市v出發可到達的城市數量為x,從某個城市出發可達到的城市v的城市數量為y,如果y>x,則城市v是一個重要城市(間接可達也算可以到達)。

      小Q希望你能幫他計算一下王國中一共有多少個重要城市。

     輸入描述:

             輸入包括 m+1行

             第一行包括兩個數n和m(1<=n,m<=1000),分別表示城市數和道路數。

             接下來m行,每行兩個樹u,v(1<=u,v<=n),表示一條從u到v的有向道路輸入中可能包含重邊和自環

      輸出秒速:

             輸出一個數,重要城市的個數。

       例子:

         輸入:

              4 3

              2 1

              3 2

              4 3

         輸出:

               2

        思路:

                  

         如題,城市一可達的城市有0個,可達城市一的城市有3個(城市2,城市3,城市4)

                    城市二可達的城市有1個,可達城市二的城市有2個(城市3,城市4)

                    城市三可達的城市有2個,可達城市三的城市有1個。

                    城市四可達的城市有3個,可達城市四的城市有0個。

                 因此最終的答案是2.

          因此我先維護一個二維的陣列,來儲存輸入的資料:(注意,我這裡加入了城市一到城市三的路徑)

                      

                        

             X表示不可達,O表示可達。

          根據題意,我們還應該再維護一個可達矩陣,因為題目給出的條件是間接可達也算是可達。

                     

          X表示不可達,O表示可達。           

          有了這個矩陣,我們可以清楚的知道,城市x可到達哪些城市。

             比如我們想知道城市一可達哪些城市,只要看第一行就可知道城市一可達兩個城市,分別是城市2和城市3。想知道哪些城市可達城市一,只要看第一列,即城市2,城市3,城市4均可達城市一。

           因此,只要我們能夠生成這個數列,就可以解出此題。

           為了夠造這個矩陣,我採用的是深度優先演算法(dfs)

           具體程式碼如下:

public class Main9 {


    public static void main(String[] args){
/**
        Scanner scanner=new Scanner(System.in);
        String a=scanner.nextLine();
        String[] strings=a.split(" ");
        int k1=Integer.valueOf(strings[0]);
        int k2=Integer.valueOf(strings[1]);
        int[][] kk=new int[k1+1][k1+1];
        for(int i=0;i<k2;i++){
            String a2=scanner.nextLine();
            String[] strings1=a2.split(" ");
            int n1=Integer.valueOf(strings1[0]);
            int n2=Integer.valueOf(strings1[1]);
            kk[n1][n2]=1;
        }
**/
        int[][] kk=new int[5][5];
        kk[1][3]=1;
        kk[2][1]=1;
        kk[3][2]=1;
        kk[4][3]=1;            //題目給出的資料

        int[][] reachable=new int[5][5];    //可達性矩陣

        for(int i=1;i<5;i++){              //通過迴圈,dfs構造每一行資料
            dfs(reachable,kk,i,i);
        }


        for(int i=1;i<reachable.length;i++){     //列印可達性矩陣
            for(int j=1;j<reachable.length;j++){
                System.out.print(reachable[i][j]);
            }
            System.out.println();
        }

        int count =0;
        for(int i=1;i<kk.length;i++){            //計算重要城市的個數
            int out=0;
            for(int d=1;d<kk.length;d++){
                if(reachable[i][d]==1){
                    out++;
                }
            }

            int in=0;
            for(int j=1;j<kk.length;j++){
                if(reachable[j][i]==1){
                    in++;
                }
            }
            if(in>out){
                count++;
            }
        }
        System.out.println(count);

    }

    /**
     *
     * @param reachable 可達性矩陣
     * @param kk        題目的原始資料
     * @param now       當前行
     * @param x         當前列
     */
    public static void dfs(int[][] reachable,int[][] kk,int now,int x){

        for(int i=1;i<reachable.length;i++){  //dfs搜尋
            if(kk[x][i]==1&&
                        now!=i&&
                            reachable[now][i]!=1){ 
                reachable[now][i]=1;
                    dfs(reachable,kk,now,i); //遞迴
            }
        }

    }
}

如有疑問,歡迎留言~