您的位置:首页 > 大数据 > 人工智能

POJ 1691 Painting A Board

2015-03-24 22:20 302 查看
一个很好的DFS题目,题意为如果一个区域的上面的区域没有被油漆,那么这快区域还不能被油漆并且每块区域的只能被油漆一次。由于每块区域要求的颜色不同,让你计算一下当所有的区域都被油漆时,最少需要更换几次颜料。

#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>

using namespace std;

const int MAX = 30;

struct Node{
int x1,y1,x2,y2,c;
}p[MAX];

vector<int> G[MAX];

int vis[MAX],in[MAX], n;      //in[i]当前情况下区域i的上面还有几个区域没有被油漆,当in[i] == 0 时,区域i才可以被染色

void check(){                 //判断区域j是不是在区域i的上面
for (int i = 0; i<n; i++)
for (int j = 0; j<n; j++){
if (i == j || p[j].y2 > p[i].y1) continue;
if (p[j].x1 < p[i].x2 && p[j].x2 > p[i].x2){
in[i]++;
G[j].push_back(i);
}
else if (p[j].x1 < p[i].x1 && p[j].x2 > p[i].x1){
in[i]++;
G[j].push_back(i);
}
else if (p[j].x1 >= p[i].x1 && p[j].x2 <= p[i].x2){
in[i]++;
G[j].push_back(i);
}
}
}

int ans;
stack<int> Q;

void dfs(int s, int res){
if (s == n){
ans = min(ans, res);
return;
}

for (int i = 0; i<n; i++) if (!vis[i] && in[i] == 0){       //译词选择当前可以被油漆的区域来油漆;
bool ok = true;
int k = i, tc = p[i].c,count = 0;
while (ok){
ok = false;
for (int j = 0; j<n; j++) if (!vis[j] && in[j] == 0 && p[j].c == tc){
vis[j] = 1;
Q.push(j);
count++;
for (int k = 0; k<G[j].size(); k++) in[G[j][k]]--;
ok = true;
}
}
dfs(s+count, res+1);
while (count--){
int u = Q.top();
Q.pop();
vis[u] = 0;
for (int j = 0; j<G[u].size(); j++) in[G[u][j]]++;
}
}
}

int main(){
int T;
scanf("%d",&T);
while (T--){
memset(in, 0, sizeof(in));
memset(vis, 0, sizeof(vis));
for (int i = 0; i<MAX; i++) G[i].clear();
while (!Q.empty()) Q.pop();

scanf("%d",&n);
for (int i=0; i<n; i++){
scanf("%d%d%d%d%d",&p[i].y1,&p[i].x1,&p[i].y2, &p[i].x2, &p[i].c);
}

check();
/*      for (int i = 0; i<n; i++) printf("%d ",in[i]); printf("\n");
for (int i = 0; i<n; i++){
for (int j = 0; j<G[i].size(); j++) printf("%d ",G[i][j]);
printf("\n");
}*/

ans = MAX;
dfs(0, 0);

printf("%d\n",ans);
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: