騰訊秋招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); //遞迴
}
}
}
}
如有疑問,歡迎留言~