試題 歷屆試題 分考場 ( dfs )

問題描述
  n個人參加某項特殊考試。
  爲了公平,要求任何兩個認識的人不能分在同一個考場。
  求是少需要分幾個考場才能滿足條件。
輸入格式
  第一行,一個整數n(1<n<100),表示參加考試的人數。
  第二行,一個整數m,表示接下來有m行數據
  以下m行每行的格式爲:兩個整數a,b,用空格分開 (1<=a,b<=n) 表示第a個人與第b個人認識。
輸出格式
  一行一個整數,表示最少分幾個考場。
樣例輸入
5
8
1 2
1 3
1 4
2 3
2 4
2 5
3 4
4 5
樣例輸出
4

Solution:

  1. 暴力枚舉所有情況 即第x個人分配在這個考場 或者 重新開一個考場 。
  2. 用 vis 數組標記關係, g 數組維護第 i 個人分配在哪個考場 。
  3. 注意考場上 大於等於 ans 時候的剪枝 。

ps: 不知道爲什麼用ArrayList數組維護每個考場分配的人數爲啥只有40分, 等這陣子學完Java再回頭來填這個坑。

代碼:

import java.math.BigInteger;
import java.util.*;

public class Main {
	  static Scanner cin = new Scanner(System.in);
	  static Main mains = new Main();	
	  
	  public static void main(String[] args) {
	      
		  long start=System.currentTimeMillis();
		  doing();
		  long end=System.currentTimeMillis(); 
	//	  System.out.println("程序運行時間:"+(end-start)+"ms");
	  }
	 
	  static int N = 100 + 5;
	  static int n, m, ans;
	  
	  static int g[] =new int[N];
	  static boolean vis[][] = new boolean[N][N];
	  
	  public static void doing() {
		  
		  n = cin.nextInt(); m = cin.nextInt();
		  for(int i = 1; i <= m; i++) {
			  int u = cin.nextInt(), v = cin.nextInt();
			  vis[u][v]=true; vis[v][u]=true;
		  }
		  ans = Integer.MAX_VALUE;
		  dfs(1, 0);
		  System.out.println(ans);
	  }

	  private static void dfs(int x, int s) {
		   if(s >= ans) return ;
		   if(x >= n+1) {
			   ans = s;
			   return ;
		   }
		   int i;
		   for(i = 1; i<= s; i++) {
			   boolean flag = true;
			   for(int y = 1; y <= n; y++) {
				   if(vis[x][y] && g[y]==i) {
					   flag = false;
					   break;
				   }
			   }
			   if(flag) {
				   g[x] = i;
				   dfs(x+1 , s);
				   g[x] = 0;
			   }
		   }
		   g[x] = s+1;
		   dfs(x+1, s+1);
		   g[x] = 0;
	  }	
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章