摘要
题目链接 |
难度等级 |
完成状态 |
完成分数 |
最后编辑时间 |
需要注意
|
四色问题
|
★☆☆☆☆
|
答案正确
|
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;
- }
|