| 题目链接 | 难度等级 | 完成状态 | 完成分数 | 最后编辑时间 | 需要注意 |
|---|---|---|---|---|---|
| 四色问题 | ★☆☆☆☆ | 答案正确 | 100 | 2014/10/15 0:14:46 | 无 |
地图相邻节点不颜色不同,共有四种颜色,求把所有点染色满的方案数。
还是搜索辣,邻接矩阵转换邻接表,然后四种颜色枚举一遍。
然后有一个问题就是判重,重复的状态容易导致冗余的搜索。我们可以用二进制压位(位运算)解决这个问题。一共四种颜色加上未染色,每个节点共5种状态,所以一个点3bit即可,最多8个点需要的空间大约为1kw左右,差不多是不会爆内存的。
然后就写了个八进制位运算的类。
That's all.
| 1116.cpp代码已折叠
展开折叠内容
|
|---|
#include<cstdio>
#include<vector>
#include<iostream>
class ocx
{
private:
int on;
public:
ocx(int u):
on(u)
{}
void set(const int &index, const int&val)
{
on&=~(7<<(index*3));
on|=(1<<(index*3))*val;
}
void printBin()//二进制逆序输出
{
int u=on;
std::cout<<"0b";
while(u)
{
std::cout<<u%2;
u>>=1;
}
std::cout<<std::endl;
}
const int operator [](const int &index)
{
return 7&(on>>(index*3));
}
operator int()
{
return on;
}
};
int count=0;
std::vector<int> map[10];
int n;
bool g[10000001]={};
void dfs(const int& painted,const int& node,ocx state)
{
for(int i=1;i<=4;++i)
{
bool accepted=1;
for(int j=0;j<map[node].size();++j)
{
if(state[map[node][j]]==i)
{
accepted=0;
break;
}
}
if(accepted)
{
state.set(node,i);
if(g[state])
continue;
g[state]=1;
if(painted == n-1)
{
++count;
continue;
}
for(int j=0;j<n;++j)
{
if(!state[j])
{
dfs(painted+1,j,state);
}
}
}
}
}
int main()
{
std::cin>>n;
for(int i=0;i<n;++i)
{
for(int j=0;j<n;++j)
{
bool b;
std::cin>>b;
if(b)
{
map[i].push_back(j);
map[j].push_back(i);
}
}
}
dfs(0,0,0);
std::cout<<count;
return 0;
}
|