ZOJ 3780 E - Paint the Grid Again 拓扑排序

https://vjudge.net/problem/49919/origin

题意:给你n*n只出现O和X的字符阵。有两种操作,一种操作Ri将i全变成X,一种操作Ci将i全变成O,每个不同的操作最多进行一次。现给出目标状态,求空盘下的字典序最小的操作顺序是怎样的。

思路:拿到题目看起来很复杂,但仔细读题会发现X和O只由特定操作出现,且操作只进行一次,那么单独地考虑每行每列,如i行中出现了O,且存在X(如果不存在X那么可以略去Ri操作),说明在Ri操作后进行了Cj的操作,同样的方法去考虑列,就能得到所有需要进行的行列操作相对顺序。这显然是个拓扑结构。那么将行操作或列操作看作点,建图拓扑排序即可。

关键还是在于建模,vijos上有道很相像的题目(1030),但比这道复杂一些还需要DFS。但是这道省赛题由于要求的复杂度不太严格,还可以模拟做。

但我居然一下子没有想出来用拓扑排序orz

weak-dish?

/** @Date    : 2017-03-27-21.44
  * @Author  : Lweleth ([email protected])
  * @Link    : https://github.com/
  * @Version :
  */
#include<bits/stdc++.h>
#define LL long long
#define PII pair
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8;
const int ost = 510;

char mp[510][510];
vectorvt[1100];
int fr[510], fc[510];
int cnt[1100];
int n;
void init()
{
    MMF(fr);
    MMF(fc);
    MMF(cnt);
    for(int i = 0; i < n + ost; i++)
        vt[i].clear();
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n; j++)
        {
            if(mp[i][j] == ‘O‘)
                fc[j] = 1;
            else fr[i] = 1;
        }
    }
    for(int i = 0; i < n; i++)
    {
        if(!fr[i]) continue;
        for(int j = 0; j < n; j++)
        {
            if(mp[i][j] == ‘O‘)
                vt[i].PB(j + ost), cnt[j + ost]++;
        }
    }
    for(int j = 0; j < n; j++)
    {
        if(!fc[j]) continue;
        for(int i = 0; i < n; i++)
        {
            if(mp[i][j] == ‘X‘)
                vt[j + ost].PB(i), cnt[i]++;
        }
    }
}

void top()
{
    int ct = 0;
    priority_queue<int, vector, greater >q;
    for(int i = 0; i < n + ost; i++)
    {
        if(cnt[i] == 0 && vt[i].size() != 0)
            q.push(i);
    }
    while(!q.empty())
    {
        int nw = q.top();
        q.pop();
        for(int i = 0; i < vt[nw].size(); i++)
        {
            int nt = vt[nw][i];
            cnt[nt]--;
            if(!cnt[nt])
                q.push(nt);
        }
        if(nw < ost)
            printf("%sR%d", ct==0?"":" ", nw + 1), ct = 1;
        else printf("%sC%d", ct==0?"":" ", nw - ost + 1), ct = 1;
    }
    if(ct == 0)
        printf("No solution");
    printf("\n");
}
int main()
{
    int T;
    cin >> T;
    while(T--)
    {
        cin >> n;
        for(int i = 0; i < n; i++)
        {
            scanf("%s", mp[i]);
        }
        init();
        top();
    }
    return 0;
}
时间: 2024-12-14 20:49:11

ZOJ 3780 E - Paint the Grid Again 拓扑排序的相关文章

zoj 3780 Paint the Grid Again (拓扑排序)

Paint the Grid Again Time Limit: 2 Seconds      Memory Limit: 65536 KB Leo has a grid with N × N cells. He wants to paint each cell with a specific color (either black or white). Leo has a magical brush which can paint any row with black color, or an

zoj3780 Paint the Grid Again 拓扑排序模拟

比赛时候看完题目就觉得是拓扑排序,当时心里隐隐觉得跟相框叠加那个题有点相似的 然后wzy问我no solution 是什么情况,我就一直去想是不是构成了什么排列就一定是no solution 其实只用再参考相框叠加那个题往前想一丁点就够了,就是从最后涂的那一层开始往前找,每一次都必然有一行或一整列是一样的 每次按逆字母序删除这一行或列就是了. 拓扑排序的题总是类似而且简单的,找到关系,敲代码完全不存在问题. #include <iostream> #include <cstring>

ZOJ - 3780-Paint the Grid Again-(拓扑排序)

Description Leo has a grid with N × N cells. He wants to paint each cell with a specific color (either black or white). Leo has a magical brush which can paint any row with black color, or any column with white color. Each time he uses the brush, the

ZOJ 3780 Paint the Grid Again(隐式图拓扑排序)

Paint the Grid Again Time Limit: 2 Seconds      Memory Limit: 65536 KB Leo has a grid with N × N cells. He wants to paint each cell with a specific color (either black or white). Leo has a magical brush which can paint any row with black color, or an

ZOJ 3780 Paint the Grid Again(topsort)

ZOJ Problem Set - 3780 Paint the Grid Again Time Limit: 2 Seconds      Memory Limit: 65536 KB Leo has a grid with N × N cells. He wants to paint each cell with a specific color (either black or white). Leo has a magical brush which can paint any row

ZOJ 3781 Paint the Grid Reloaded (最短路)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 题意: 在n*m矩阵的图定义连通区域为x值或y值相同且颜色相同的连通,连通具有传递性 每次可以把一个连通区域颜色反转(O变X,X变O) 问把所有块的颜色变为X最小的步数 方法: 很巧妙的最短路问题,先建图,然后以每个顶点为起点,找单源最短路的最大的值(也就是最深的深度),然后这个值取min 建图:相邻的块连边权1的边(即:通过1次反转可以使得两个连通块变为一个连通块

zoj 3781 Paint the Grid Reloaded (比较隐含的最短路)

Paint the Grid Reloaded Time Limit: 2 Seconds      Memory Limit: 65536 KB Leo has a grid with N rows and M columns. All cells are painted with either black or white initially. Two cells A and B are called connected if they share an edge and they are

zjuoj 3780 Paint the Grid Again

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3780 Paint the Grid Again Time Limit: 2 Seconds      Memory Limit: 65536 KB Leo has a grid with N × N cells. He wants to paint each cell with a specific color (either black or white). Leo h

ZOJ 3781 Paint the Grid Reloaded(BFS)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 Leo has a grid with N rows and M columns. All cells are painted with either black or white initially. Two cells A and B are called connected if they share an edge and they are in