演算法設計例題:最大團(回溯、分枝限界)
阿新 • • 發佈:2020-12-04
Description
Sample Input
給定無向圖G=(V,E)。如果UV,且對任意u, v ∈ U 有 (u,v) ∈ E,則稱U是G的完全子圖。G的完全子圖U是G的團,當且僅當U不包含在G的更大的完全子圖中。G的最大團是指G中所含頂點數最多的團。
Input輸入的第一行為測試樣例的個數T ,接下來有T個測試樣例。每個測試樣例的第一行是 頂點數n 和 邊數m ( n ≤ 20,m ≤ 400 ),接下來m行,每行兩個整數u和v,表示頂點u和v之間有一條邊相連。( 1 ≤ u < v ≤ n )。
Output對應每個測試樣例輸出兩行,第一行格式為"Case #: M",其中'#'表示第幾個測試樣例(從1開始計),M為最大團頂點數。
1
5 7
1 2
1 4
1 5
2 3
2 5
3 5
4 5
Case 1: 3
深搜做法#include<bits/stdc++.h> #define ll long long const int maxn = 1e3+10; using namespace std; bool a[30][30],res; int n,ans; vector<int>v; void solve(int j){ if(j>n){ if(ans<v.size())ans=v.size(); res=1;return; } bool ss=0; for(int i=0;i<v.size();i++) if(a[j][v[i]]==0){ ss=1;break; } if(!ss){ v.push_back(j); solve(j+1); v.pop_back(); } solve(j+1); } int main() { int t,cas=0;cin>>t; while(t--){ res=0; ans=0; v.clear(); memset(a,0,sizeof(a)); int m; cin>>n>>m; for(int i=1;i<=m;i++){ int x,y; cin>>x>>y; a[x][x]=a[x][y]=a[y][y]=a[y][x]=1; } solve(1); printf("Case %d: %d\n",++cas,ans); } }
廣搜做法
#include<bits/stdc++.h> #define pd putchar(' ') #define pn putchar('\n') #define pb push_back #define fi first #define se second #define f1(i,j,n) for(int i=j;i<n;i++) #define f2(i,j,n) for(int i=j;i<=n;i++) #define mem(i,j) memset(i,j,sizeof(i)) #define INF 0x3f3f3f3f #define PI acos(-1.0) #define ll long long #define jiasu ios::sync_with_stdio(false) #define P1 printf("yes\n") #define P2 printf("No\n") const ll mod =1e8+9; const ll modd=998244353; const ll maxn = 1e3+10; const double eps=1e-7; using namespace std; struct num{ int now,res,ans; }; int a[30][30]; bool solve(int x,int y){ int countt=0; while(x){ countt++; int res=x%2; if(res&&!a[y][countt]) return false; x=x>>1; } return true; } int main() { int _,cas=0;scanf("%d",&_); while(_--){ int n,m,ans=0; scanf("%d%d",&n,&m); f2(i,1,n) f2(j,1,n)a[i][j]=0; f2(i,1,m){ int x,y; scanf("%d%d",&x,&y); a[x][y]=a[y][x]=1; } queue<num>q; q.push({0,0,0}); while(!q.empty()){ num temp=q.front(); q.pop(); if(temp.now>=n)continue; q.push({temp.now+1,temp.res,temp.ans}); if(solve(temp.res,temp.now+1)){ temp.res=temp.res|(1<<temp.now); temp.ans++; ans=ans>temp.ans?ans:temp.ans; q.push(temp); } } printf("Case %d: %d\n",++cas,ans); } return 0; }