pku 1691 painting a board dfs+回溯 解题报告
2009-12-11 15:47
197 查看
pku 1691 painting a board 解题报告
算法:
先将数据转化为有向图,然后dfs+回溯.
如sample中的数据可以变为以下的有向图:
然后利用深度搜索+回溯,求出最优值.
AC代码:
#include <stdio.h>
#include <string.h>
#define M 20
#define inf 1000000
int n;
int map[M][M], degree[M], r[M], color_num;
void init()
{
int i, j;
int a[M], b[M], c[M], d[M];
scanf("%d", &n);
color_num = 0;
for (i = 1; i <= n; i++)
{
scanf("%d%d%d%d%d", &a[i], &b[i], &c[i], &d[i], &r[i]);
if (color_num > r[i])
{
color_num = r[i];
}
}
//建立有向图
memset(map, 0, sizeof(map));
memset(degree, 0, sizeof(degree));
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
if (i != j && c[i] == a[j] && a[i] < a[j] && !((d[i] <= b[j]) || (d[j] <= b[i])))
{
map[i][j] = 1;
degree[j]++;
}
}
}
/*for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
printf("%d ", map[i][j]);
}
printf("/n");
}
printf("/n");*/
}
int visit[M];
int solve(int color, int count)
{
int ans = inf;
int i, j, k;
for (i = 1; i <= n; i++)
{
if (degree[i] == 0 && visit[i] == 0)
{
visit[i] = 1;
//颜色不一样,那么count就相加
if (r[i] != color)
{
count++;
}
//i相应的儿子j的入度-1
for (j = 1; j <= n; j++)
{
if (map[i][j])
{
degree[j]--;
}
}
//搜索
k = solve(r[i], count);
//取最优值
if (k < ans)
{
ans = k;
}
//回溯
for (j = 1; j <= n; j++)
{
if (map[i][j])
{
degree[j]++;
}
}
visit[i] = 0;
if (r[i] != color)
{
count--;
}
}
}
if (ans == inf)
{
ans = count;
}
return ans;
}
int main()
{
//freopen("1.txt", "r", stdin);
int test;
scanf("%d", &test);
while (test--)
{
init();
memset(visit, 0, sizeof(visit));
printf("%d/n", solve(-1, 0));
}
return 0;
}
算法:
先将数据转化为有向图,然后dfs+回溯.
如sample中的数据可以变为以下的有向图:
然后利用深度搜索+回溯,求出最优值.
AC代码:
#include <stdio.h>
#include <string.h>
#define M 20
#define inf 1000000
int n;
int map[M][M], degree[M], r[M], color_num;
void init()
{
int i, j;
int a[M], b[M], c[M], d[M];
scanf("%d", &n);
color_num = 0;
for (i = 1; i <= n; i++)
{
scanf("%d%d%d%d%d", &a[i], &b[i], &c[i], &d[i], &r[i]);
if (color_num > r[i])
{
color_num = r[i];
}
}
//建立有向图
memset(map, 0, sizeof(map));
memset(degree, 0, sizeof(degree));
for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
if (i != j && c[i] == a[j] && a[i] < a[j] && !((d[i] <= b[j]) || (d[j] <= b[i])))
{
map[i][j] = 1;
degree[j]++;
}
}
}
/*for (i = 1; i <= n; i++)
{
for (j = 1; j <= n; j++)
{
printf("%d ", map[i][j]);
}
printf("/n");
}
printf("/n");*/
}
int visit[M];
int solve(int color, int count)
{
int ans = inf;
int i, j, k;
for (i = 1; i <= n; i++)
{
if (degree[i] == 0 && visit[i] == 0)
{
visit[i] = 1;
//颜色不一样,那么count就相加
if (r[i] != color)
{
count++;
}
//i相应的儿子j的入度-1
for (j = 1; j <= n; j++)
{
if (map[i][j])
{
degree[j]--;
}
}
//搜索
k = solve(r[i], count);
//取最优值
if (k < ans)
{
ans = k;
}
//回溯
for (j = 1; j <= n; j++)
{
if (map[i][j])
{
degree[j]++;
}
}
visit[i] = 0;
if (r[i] != color)
{
count--;
}
}
}
if (ans == inf)
{
ans = count;
}
return ans;
}
int main()
{
//freopen("1.txt", "r", stdin);
int test;
scanf("%d", &test);
while (test--)
{
init();
memset(visit, 0, sizeof(visit));
printf("%d/n", solve(-1, 0));
}
return 0;
}
相关文章推荐
- pku 1691 Painting A Board DFS 抽象建图 + 拓扑排序
- hdu 5547 Sudoku dfs 暴力回溯 解题报告
- POJ 1691 Painting A Board(dfs搜索)
- pku 1691 Painting A Board 状态压缩dp
- 第七届 蓝桥杯决赛 Java B组 打靶 解题报告(DFS,回溯,全排列)
- poj 1691 Painting A Board (构图 DFS)
- poj1691--Painting A Board(拓扑+dfs)
- poj_1691 Painting A Board(dfs+拓扑)
- pku 1129 channel allocation 回溯解题报告
- BJFUOJ 1042解题报告(DFS回溯策略总结)
- POJ 1691 Painting A Board(DFS)
- POJ1190 生日蛋糕 ACM解题报告(DFS回溯+剪枝)
- BJFUOJ 1042解题报告(DFS回溯策略总结)
- pku 1691 Painting A Board(据说可以用状态压缩DP)
- poj1691--Painting A Board(拓扑+dfs)
- poj 1691 Painting A Board(dfs,拓扑排序)
- [POJ 1691]Painting A Board[DFS][排序]
- POJ 题目1691 Painting A Board(DFS)
- 【POJ 1691】 Painting A Board(dfs)
- pku 1087 A Plug for UNIX 网络流 解题报告