关于BFS写最大团的实现方法
写在前面: 因为算法与分析课上布置了用广搜写最大团的题目。查找资料后 ,发现大部分都是用DFS写的。BFS方法实现确实能拓宽思路,虽然会怀疑因为没有剪枝,会不会爆空间的风险。
思路:
对最大团可能的个数进行枚举。即找出所有大小为i的团,推入队列中。每次查找新团时,选原团中下表最大的节点为为起点,讨论之后每个点能不能加入团中,可以的话,记录新的状态,推入队列。
note:
这种方法将所有团的可能都枚举了一遍,ACM竞赛碰到千万不要有,估计也碰不到。ACM算法题中的团,可能关联到最大独立集,变成用二分图匹配(KM算法等)解决。这题只是因为题目要求了才尝试BFS方法。
代码:
#include<bits/stdc++.h>
using namespace std;
#define f(i,n) for(i=0;i<n;i++)
int ans,n;
bool index[100][100];
class node //当前某种情况
{
public:
vector<int> vec;
int num;//包括的点
node(int i)
{
num=1;
vec.push_back(i);
}
node()
{
}
//只往后找
node pushed(int sum)
{
node newd;
newd.vec=this->vec;
newd.num=this->num+1;
newd.vec.push_back(sum);
return newd;
}
};
queue<node> que;
void init()
{
cin>>n;
int i,j;
f(i,n)
f(j,n)
{
cin>>index[i][j];
//默认无环
if(i==j) index[i][i]=0;
}
ans=1;
f(i,n)
{
node k=node(i);
que.push(k);
}
}
void bfs()
{
node nd;
int i,j;
while(!que.empty())
{
nd=que.front();
que.pop();
int last=nd.vec.back();
int k=nd.vec.size()-1;
//因为是bfs,每层的极大团的大小都是一样,剪枝不起作用。
// //剪枝
// if(n-last+k+1<ans) continue;
//增点
for(i=last+1; i<n; i++)
{
//邻接矩阵,自身不连接
if(index[i][last])
{
f(j,k)
{
if(!index[nd.vec[j]][i])break;
}
if(j==k)
{
que.push(nd.pushed(i));
if(k+1==ans)
ans++;
}
}
}
}
}
int main()
{
#ifdef _zxdin_
freopen("data.in","r",stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
init();
bfs();
cout<<"the ans is :\t"<<ans<<endl;
return 0;
}