CCF-CSP 通訊網路 JAVA 201709-4 100分
阿新 • • 發佈:2019-02-17
思路:
我不知道標準解法是怎麼樣的,反正我為我“禁忌的解法”解得100分感到很開心=。=
首先使用list,製作好圖的鄰接表。
一個是
1→2→3
2→4
3→4
4
一個是
1
2→1
3→1
4→2→3
為什麼要分兩個鄰接表呢,因為一個鄰接表不能正確的表示我們要的結果。(自己體悟吧。。。 表1確定傳送訊號方有哪些全知,表2確定接受訊號方有哪些全知)
接下來我們做一個n*n(為去掉0實際n+1 * n+1)的二維陣列 vis
vis[i][j] 表示 點i和點j是否可以連通
最終只要j從1到n都為true(都連通) 則部門i全知,ans++
那麼下面實際操作:只需要用bfs或者dfs做一下這個vis表就可以了
package csp2017_09_4; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Scanner; public class Main{ static List<Integer> list[]; static List<Integer> list2[]; static boolean vis [][] ; static boolean vn[]; static int n,m; public static void main(String[] args){ Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); list = new ArrayList[n+1]; list2 = new ArrayList[n+1]; for (int i = 0; i < list.length; i++) { list[i] = new ArrayList<Integer>(); list2[i] = new ArrayList<Integer>(); } for (int i = 0; i < m; i++) { int s = sc.nextInt(); int e = sc.nextInt(); list[s].add(e); list2[e].add(s); } vis = new boolean[n+1][n+1]; for (int i = 0; i < vis.length; i++) { vis[i][i] = true; } //bfs Queue<Integer> q = new LinkedList(); for (int t = 1; t <= n; t++) { q.add(t); vn = new boolean[n+1]; while(!q.isEmpty()){ int temp = q.poll(); if(!vn[temp]){ for (int i = 0; i < list[temp].size(); i++) { int next = list[temp].get(i); q.add(next); } vn[temp] = true; vis[t][temp] = true; } } } for (int t = 1; t <= n; t++) { q.add(t); vn = new boolean[n+1]; while(!q.isEmpty()){ int temp = q.poll(); if(!vn[temp]){ for (int i = 0; i < list2[temp].size(); i++) { int next = list2[temp].get(i); q.add(next); } vn[temp] = true; vis[t][temp] = true; } } } // for (int i = 1; i < vis.length; i++) { // for (int j = 1; j < vis[i].length; j++) { // if(vis[i][j])System.out.print(1+" "); // else System.out.print(0+" "); // } // System.out.println(); // } int ans = 0; for (int i = 1; i < vis.length; i++) { boolean knowAll = true; for (int j = 1; j < vis[i].length; j++) { if(!vis[i][j]){knowAll = false;break; } } if(knowAll) ans++; } System.out.println(ans); } }
問題描述
試題編號: | 201709-4 |
試題名稱: | 通訊網路 |
時間限制: | 1.0s |
記憶體限制: | 256.0MB |
問題描述: |
問題描述
某國的軍隊由N個部門組成,為了提高安全性,部門之間建立了M條通路,每條通路只能單向傳遞資訊,即一條從部門a到部門b的通路只能由a向b傳遞資訊。資訊可以通過中轉的方式進行傳遞,即如果a能將資訊傳遞到b,b又能將資訊傳遞到c,則a能將資訊傳遞到c。一條資訊可能通過多次中轉最終到達目的地。 由於保密工作做得很好,並不是所有部門之間都互相知道彼此的存在。只有當兩個部門之間可以直接或間接傳遞資訊時,他們才彼此知道對方的存在。部門之間不會把自己知道哪些部門告訴其他部門。 上圖中給了一個4個部門的例子,圖中的單向邊表示通路。部門1可以將訊息傳送給所有部門,部門4可以接收所有部門的訊息,所以部門1和部門4知道所有其他部門的存在。部門2和部門3之間沒有任何方式可以傳送訊息,所以部門2和部門3互相不知道彼此的存在。 現在請問,有多少個部門知道所有N個部門的存在。或者說,有多少個部門所知道的部門數量(包括自己)正好是N。 輸入格式 輸入的第一行包含兩個整數N, M,分別表示部門的數量和單向通路的數量。所有部門從1到N標號。 接下來M行,每行兩個整數a, b,表示部門a到部門b有一條單向通路。 輸出格式 輸出一行,包含一個整數,表示答案。 樣例輸入 4 4 1 2 1 3 2 4 3 4 樣例輸出 2 樣例說明 部門1和部門4知道所有其他部門的存在。 評測用例規模與約定 對於30%的評測用例,1 ≤ N ≤ 10,1 ≤ M ≤ 20; 對於60%的評測用例,1 ≤ N ≤ 100,1 ≤ M ≤ 1000; 對於100%的評測用例,1 ≤ N ≤ 1000,1 ≤ M ≤ 10000。 |