poj 1691
2016-02-16 10:56
344 查看
题目大意:
墙上有一块区域被分成了n个矩形,每个矩形要涂上各自的颜色。为了保证完美要求这一块区域可以进行涂色的条件是它上方的所有区域都已经涂好颜色,这样就不会有后续的操作影响这块区域的颜色。但是如果两块区域颜色不同就要换涂颜色用的刷子。问最少需要换几次。
解题思路:由于这题有一个限制条件,即上方的所有区域都已经涂好颜色,所以肯定是要求一个满足条件的拓扑序列,既然这样就很好办了,把上下两个相邻的矩形建立一条由上到下的有向边,然后dfs去搜索满足条件的拓扑序列。
AC:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f;
struct node
{
int xl,yl,xr,yr;
int c;
}rec[20];
struct Edge
{
int k,next;
}edge[50];
int n,cnt,pre[50],indegree[50],ans;
bool vis[20];
bool cmp(node a,node b)
{
return a.yl < b.yl;
}
void addedge(int u,int v)
{
edge[cnt].k = v;
edge[cnt].next = pre[u];
pre[u] = cnt++;
}
void dfs(int cur,int tmp,int dep)
{
if(dep == n) //所有点都找到
{
if(tmp < ans) ans = tmp;
return;
}
if(tmp >= ans) return; //当前的解大于已知最优解
for(int i = pre[cur]; i != -1; i = edge[i].next)
{
int k = edge[i].k;
indegree[k]--;
}
for(int i = 1; i <= n; i++)
{
if(vis[i] == true) continue;
if(indegree[i] == 0)
{
vis[i] = true;
if(rec[i].c != rec[cur].c)
dfs(i,tmp+1,dep+1);
else dfs(i,tmp,dep+1);
vis[i] = false;
}
}
for(int i = pre[cur]; i != -1; i = edge[i].next) //把修改的入度恢复原状
{
int k = edge[i].k;
indegree[k]++;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(pre,-1,sizeof(pre));
memset(vis,false,sizeof(vis));
memset(indegree,0,sizeof(indegree));
cnt = 0;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d%d%d%d%d",&rec[i].yl,&rec[i].xl,&rec[i].yr,&rec[i].xr,&rec[i].c);
sort(rec+1,rec+1+n,cmp);
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
{
if(rec[i].yr != rec[j].yl) continue;
if(rec[i].xl >= rec[j].xl && rec[i].xr <= rec[j].xr)
{
addedge(i,j);
indegree[j]++;
}
else if(rec[i].xl <= rec[j].xl && rec[i].xr >= rec[j].xr)
{
addedge(i,j);
indegree[j]++;
}
else if(rec[i].xl < rec[j].xr && rec[i].xl > rec[j].xl)
{
addedge(i,j);
indegree[j]++;
}
else if(rec[i].xr < rec[j].xr && rec[i].xr > rec[j].xl)
{
addedge(i,j);
indegree[j]++;
}
}
ans = inf;
for(int i = 1; i <= n; i++)
if(indegree[i] == 0)
{
vis[i] = true;
dfs(i,1,1);
vis[i] = false;
}
printf("%d\n",ans);
}
return 0;
}
墙上有一块区域被分成了n个矩形,每个矩形要涂上各自的颜色。为了保证完美要求这一块区域可以进行涂色的条件是它上方的所有区域都已经涂好颜色,这样就不会有后续的操作影响这块区域的颜色。但是如果两块区域颜色不同就要换涂颜色用的刷子。问最少需要换几次。
解题思路:由于这题有一个限制条件,即上方的所有区域都已经涂好颜色,所以肯定是要求一个满足条件的拓扑序列,既然这样就很好办了,把上下两个相邻的矩形建立一条由上到下的有向边,然后dfs去搜索满足条件的拓扑序列。
AC:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f;
struct node
{
int xl,yl,xr,yr;
int c;
}rec[20];
struct Edge
{
int k,next;
}edge[50];
int n,cnt,pre[50],indegree[50],ans;
bool vis[20];
bool cmp(node a,node b)
{
return a.yl < b.yl;
}
void addedge(int u,int v)
{
edge[cnt].k = v;
edge[cnt].next = pre[u];
pre[u] = cnt++;
}
void dfs(int cur,int tmp,int dep)
{
if(dep == n) //所有点都找到
{
if(tmp < ans) ans = tmp;
return;
}
if(tmp >= ans) return; //当前的解大于已知最优解
for(int i = pre[cur]; i != -1; i = edge[i].next)
{
int k = edge[i].k;
indegree[k]--;
}
for(int i = 1; i <= n; i++)
{
if(vis[i] == true) continue;
if(indegree[i] == 0)
{
vis[i] = true;
if(rec[i].c != rec[cur].c)
dfs(i,tmp+1,dep+1);
else dfs(i,tmp,dep+1);
vis[i] = false;
}
}
for(int i = pre[cur]; i != -1; i = edge[i].next) //把修改的入度恢复原状
{
int k = edge[i].k;
indegree[k]++;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(pre,-1,sizeof(pre));
memset(vis,false,sizeof(vis));
memset(indegree,0,sizeof(indegree));
cnt = 0;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
scanf("%d%d%d%d%d",&rec[i].yl,&rec[i].xl,&rec[i].yr,&rec[i].xr,&rec[i].c);
sort(rec+1,rec+1+n,cmp);
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
{
if(rec[i].yr != rec[j].yl) continue;
if(rec[i].xl >= rec[j].xl && rec[i].xr <= rec[j].xr)
{
addedge(i,j);
indegree[j]++;
}
else if(rec[i].xl <= rec[j].xl && rec[i].xr >= rec[j].xr)
{
addedge(i,j);
indegree[j]++;
}
else if(rec[i].xl < rec[j].xr && rec[i].xl > rec[j].xl)
{
addedge(i,j);
indegree[j]++;
}
else if(rec[i].xr < rec[j].xr && rec[i].xr > rec[j].xl)
{
addedge(i,j);
indegree[j]++;
}
}
ans = inf;
for(int i = 1; i <= n; i++)
if(indegree[i] == 0)
{
vis[i] = true;
dfs(i,1,1);
vis[i] = false;
}
printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- 搜狗百度360市值齐跌:搜索引擎们陷入集体焦虑?
- 本人即将筹备败家日志,敬请期待!
- IE:使用搜索助手
- C++深度优先搜索的实现方法
- 基于文本的搜索
- php实现搜索一维数组元素并删除二维数组对应元素的方法
- 使用Sphinx对索引进行搜索
- asp 多关键词搜索的简单实现方法
- C#使用foreach语句搜索数组元素的方法
- WordPress中用于获取搜索表单的PHP函数使用解析
- JavaScript中数组的排序、乱序和搜索实现代码
- C#编程实现Excel文档中搜索文本内容的方法及思路
- sqlserver中在指定数据库的所有表的所有列中搜索给定的值
- 可以用来搜索当前页面内容的js代码
- 全文搜索和替换
- javascript搜索自动提示功能的实现第1/3页
- mysql 模糊搜索的方法介绍
- C#搜索文字在文件及文件夹中出现位置的方法
- 基于ajax的简单搜索实现方法
- Android自定义View软键盘实现搜索