問題描述
n個人參加某項特殊考試。
爲了公平,要求任何兩個認識的人不能分在同一個考場。
求是少需要分幾個考場才能滿足條件。
輸入格式
第一行,一個整數n(1<n<100),表示參加考試的人數。
第二行,一個整數m,表示接下來有m行數據
以下m行每行的格式爲:兩個整數a,b,用空格分開 (1<=a,b<=n) 表示第a個人與第b個人認識。
輸出格式
一行一個整數,表示最少分幾個考場。
最近的思維定勢特別多,需要改正。第一眼看這題,woc這肯定是最大團了。畢竟一個子完全圖的各個端點肯定屬於不同的考場。迅速地寫了一發交上去WA。後來想了一段時間才意識到根本和最大團沒啥關係,答案的數目完全可以比最大團的大小要大。一個例子就是五個端點的環,最大團是2,然而必須要三個教室,類似的圖還有:
這個圖最大團是3,但是拿三色去染會發生矛盾,至少需要四色。
實際上這題的解法,還是需要暴搜,從左到右枚舉每個編號的同學,枚舉他能呆在哪個已有的教室,或是呆在一個新教室。乍一看100好像很大,實際上寫得正常的話都可以過,數據不那麼噁心。
#include<cstdio> #include<vector> #include<algorithm> #include<bitset> using namespace std; int n,m,cnt,ans=1E9,h[105]; vector<int> E[105]; bitset<105> B[105]; bool get(int x) //提取可能選擇 { for(int j=0;j<E[x].size();j++) if(h[E[x][j]]) B[x][h[E[x][j]]]=true; } void dfs(int x) { if(cnt>=ans) return ; if(x>n) { ans=cnt; return ; } B[x].reset(); get(x); for(int i=1;i<=cnt;i++) if(!B[x][i]) { h[x]=i; dfs(x+1); h[x]=0; } cnt++; h[x]=cnt; dfs(x+1); //新教室 h[x]=0; cnt--; } int main() { scanf("%d%d",&n,&m); for(int i=1,u,v;i<=m;i++) { scanf("%d%d",&u,&v); if(u>v) swap(u,v); E[v].push_back(u); } for(int i=1;i<=n;i++) sort(E[i].begin(),E[i].end()),unique(E[i].begin(),E[i].end()); dfs(1); printf("%d",ans); return 0; }