loj 1406(状态压缩)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1406

思路:首先可以预处理出在每个顶点的状态的合法状态vis[u][state], 然后标记那些合法状态mark[state]。最后就是记忆化搜索了,对于当前状态state,我们有res = min(res, 1 + Solve(state ^ substate)), 其中substate为state的子状态,并且substate = (substate  - 1) & state.那么最终就是要求Solve((1 << n) - 1)了。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; int n, m;
bool vis[][ << ];
bool mark[ << ];
int dp[ << ];
vector<int > g[]; void dfs(int u, int state)
{
vis[u][state] = true;
mark[state] = true;
for (int i = ; i < (int)g[u].size(); i++) {
int v = g[u][i];
if (!vis[v][state | ( << v)]) {
dfs(v, state | ( << v));
}
}
} int Solve(int state)
{
if (state == ) return ;
if (dp[state] != -) return dp[state];
int res = ;
for (int i = state; i > ; i = (i - ) & state) {
if (mark[i]) {
res = min(res, + Solve(state ^ i));
}
}
return dp[state] = res;
} int main()
{
int _case, t = ;
scanf("%d", &_case);
while (_case--) {
scanf("%d %d", &n, &m);
for (int i = ; i < n; i++) g[i].clear();
while (m--) {
int u, v;
scanf("%d %d", &u, &v);
u--, v--;
g[u].push_back(v);
}
memset(vis, false, sizeof(vis));
memset(mark, false, sizeof(mark));
for (int i = ; i < n; i++) dfs(i, << i);
memset(dp, -, sizeof(dp));
printf("Case %d: %d\n", t++, Solve(( << n) -));
}
return ;
}
上一篇:MySQL运维---XBK备份


下一篇:【最小生成树】UVA1494Qin Shi Huang's National Road System秦始皇修路