codeforces 515d 拓撲排序/二分圖

D. Drazil and Tiles
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Drazil created a following problem about putting 1 × 2 tiles into an n × m grid:

"There is a grid with some cells that are empty and some cells that are occupied. You should use 1 × 2 tiles to cover all empty cells and no two tiles should cover each other. And you should print a solution about how to do it."

But Drazil doesn't like to write special checking program for this task. His friend, Varda advised him: "how about asking contestant only to print the solution when it exists and it is unique? Otherwise contestant may print 'Not unique' ".

Drazil found that the constraints for this task may be much larger than for the original task!

Can you solve this new problem?

Note that you should print 'Not unique' either when there exists no solution or when there exists several different solutions for the original task.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 2000).

The following n lines describe the grid rows. Character '.' denotes an empty cell, and the character '*' denotes a cell that is occupied.

Output

If there is no solution or the solution is not unique, you should print the string "Not unique".

Otherwise you should print how to cover all empty cells with 1 × 2 tiles. Use characters "<>" to denote horizontal tiles and characters "^v" to denote vertical tiles. Refer to the sample test for the output format example.

Sample test(s)
input
3 3
...
.*.
...
output
Not unique
input
4 4
..**
*...
*.**
....
output
<>**
*^<>
*v**
<><>
input
2 4
*..*
....
output
*<>*
<><>
input
1 1
.
output
Not unique
input
1 1
*
output
*
Note

In the first case, there are indeed two solutions:

<>^
^*v
v<>

and

^<>
v*^
<>v

so the answer is "Not unique".



題目給出一個n*m的網格,用1*2的磚塊將上面的空地都鋪滿,輸出方案是否唯一,若唯一輸出解決方案。

把所有的格子當成點,相鄰格子間連接一條邊,並統計每個格子的度數。將所有度數爲1的點放入隊列中,度數爲1的一定只有一種鋪法。鋪完更新周圍的點的度數,將度數爲1的入隊,循環直到隊列爲空。如果此時還沒鋪滿,則方案不唯一。

如果鋪完度數爲1的,那麼剩下的點都是度數>=2,所有的邊構成了一個二分圖,並且一定存在一個環其中相鄰的邊可以染成不同顏色。所以如果有解則一定有>=2個解


#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>

using namespace std;

#define maxn 2005

int n,m;
char g[maxn][maxn];
int d[maxn][maxn];
int dir[4][2] = {{-1,0},{1,0},{0,1},{0,-1}};

int main()
{
    while(scanf("%d%d", &n, &m)!=EOF){
        for(int i = 1; i <= n; i++)
            scanf("%s", g[i]+1);

        memset(d, 0, sizeof(d));
        int tot = 0;

        queue<int> q;
        for(int i = 1; i<= n;i++)
        for(int j =1; j<= m; j++){
            int nx,ny;
            if(g[i][j] != '.') continue;
            tot++;
            for(int k = 0; k < 4; k++){
                nx = i+dir[k][0], ny = j+dir[k][1];
                if(g[nx][ny] == '.')
                    d[i][j]++;
            }
            if(d[i][j] == 1)
                q.push(i*(m+1)+j);
        }

        int cnt = 0;
        while(!q.empty()){
            int x = q.front()/(m+1), y = q.front()%(m+1);
            q.pop();

            for(int i = 0; i < 4; i++){
                int nx = dir[i][0]+x, ny = dir[i][1]+y;
                if(g[nx][ny] != '.') continue;
                if(i == 0){
                    g[nx][ny] = '^';
                    g[x][y] = 'v';
                }
                else if(i == 1){
                    g[nx][ny] = 'v';
                    g[x][y] = '^';
                }
                else if(i == 2){
                    g[nx][ny] = '>';
                    g[x][y] = '<';
                }
                else{
                    g[nx][ny] = '<';
                    g[x][y] = '>';
                }

                cnt+=2;
                for(int k = 0; k < 4; k++){
                int nnx = nx+dir[k][0], nny = ny+dir[k][1];
                if(g[nnx][nny]!='.') continue;
                d[nnx][nny]--;
                if(d[nnx][nny] == 1)
                    q.push(nnx*(m+1)+nny);
                }

            }
        }

        if(cnt!=tot)
            printf("Not unique\n");
        else{
            for(int i = 1; i <= n; i++){
                for(int j = 1; j <= m; j++)
                    printf("%c", g[i][j]);
                printf("\n");
            }
        }

    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章