poj_1691 Painting A Board(dfs+拓扑)

来源:互联网 发布:分类信息网站源码 编辑:程序博客网 时间:2024/06/05 05:30
Painting A Board
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 3797 Accepted: 1879

Description

The CE digital company has built an Automatic Painting Machine (APM) to paint a flat board fully covered by adjacent non-overlapping rectangles of different sizes each with a predefined color.

To color the board, the APM has access to a set of brushes. Each brush has a distinct color C. The APM picks one brush with color C and paints all possible rectangles having predefined color C with the following restrictions:
To avoid leaking the paints and mixing colors, a rectangle can only be painted if all rectangles immediately above it have already been painted. For example rectangle labeled F in Figure 1 is painted only after rectangles C and D are painted. Note that each rectangle must be painted at once, i.e. partial painting of one rectangle is not allowed.
You are to write a program for APM to paint a given board so that the number of brush pick-ups is minimum. Notice that if one brush is picked up more than once, all pick-ups are counted.

Input

The first line of the input file contains an integer M which is the number of test cases to solve (1 <= M <= 10). For each test case, the first line contains an integer N, the number of rectangles, followed by N lines describing the rectangles. Each rectangle R is specified by 5 integers in one line: the y and x coordinates of the upper left corner of R, the y and x coordinates of the lower right corner of R, followed by the color-code of R.
Note that:
  1. Color-code is an integer in the range of 1 .. 20.
  2. Upper left corner of the board coordinates is always (0,0).
  3. Coordinates are in the range of 0 .. 99.
  4. N is in the range of 1..15.

Output

One line for each test case showing the minimum number of brush pick-ups.

Sample Input

170 0 2 2 10 2 1 6 22 0 4 2 11 2 4 4 21 4 3 6 14 0 6 4 13 4 6 6 2

Sample Output

3
将矩形设为顶点,若矩形i有紧贴着下边缘的矩形j,则i到j连一条有向边,这样很明显就是按拓扑序涂色了。
直接暴力就能过,想了一下,数据量不大,用一个整数来表示目前矩形涂色与否的状态,然后根据状态与目前刷子的颜色来记忆化搜索应该可行。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>#include <bitset>#include <queue>#include <set>#include <map>#include <string>#include <algorithm>#define FOP freopen("data.txt","r",stdin)#define FOP2 freopen("data1.txt","w",stdout)#define inf 0x3f3f3f3f#define maxn 22#define mod 1000000007#define PI acos(-1.0)#define LL long longusing namespace std;struct Node{    int x1, y1, x2, y2, color, indegree;    bool flag;    Node(int _x1, int _y1, int _x2, int _y2, int _color) : x1(_x1), y1(_y1), x2(_x2), y2(_y2), color(_color)    {        indegree = 0, flag = 0;    }};struct Edge{    int from, to;    Edge(int u, int v) : from(u), to(v) {}};int n, m;vector<int> G[maxn];vector<Edge> edges;int ans;vector<Node> nodes;void init(){    ans = inf;    for(int i = 1; i <= n; i++) G[i].clear();    edges.clear();    nodes.clear();}void AddEdge(int from, int to){    edges.push_back(Edge(from, to));    m = edges.size();    G[from].push_back(m-1);}void dfs(int nn, int col, int cot){    if(cot >= ans) return ; //剪枝        if(nn == n)    {        if(ans > cot) ans = cot;        return ;    }    for(int i = 1; i <= n; i++)    {        if(!nodes[i].flag && nodes[i].indegree == 0)        {            nodes[i].flag = 1;            for(int j = 0; j < G[i].size(); j++)            {                Edge &e = edges[G[i][j]];                nodes[e.to].indegree--;            }            if(nodes[i].color != col) dfs(nn+1, nodes[i].color, cot+1);            else dfs(nn+1, col, cot);            nodes[i].flag = 0;            for(int j = 0; j < G[i].size(); j++)            {                Edge &e = edges[G[i][j]];                nodes[e.to].indegree++;            }        }    }}int main(){    int T;    scanf("%d", &T);    while(T--)    {        init();        scanf("%d", &n);        int x1, x2, y1, y2, color;        nodes.push_back(Node(0, 0, 0, 0, 0));        for(int i = 1; i <= n; i++)        {            scanf("%d%d%d%d%d", &y1, &x1, &y2, &x2, &color);            nodes.push_back(Node(x1, y1, x2, y2, color));        }        for(int i = 1; i <= n; i++)        {            for(int j = 1; j <= n; j++)            {                if(i == j) continue;                if(nodes[i].y2 == nodes[j].y1 && nodes[i].x2 > nodes[j].x1 && nodes[i].x1 < nodes[j].x2)                {                    AddEdge(i, j);                    nodes[j].indegree++;                }            }        }        dfs(0, 0, 0);        printf("%d\n", ans);    }    return 0;}


0 0