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

zoj 3780 Paint the Grid Again 拓扑排序

2014-04-17 16:15 387 查看
表示完全没想到是拓扑,而且题目又读错了。。。

拓扑排序的题目,有许多的任务以及它们进行的先后关系,排序,找出一个序列,使得满足它们的先后关系要求!!!

本题中的任务就是,在行和列上涂颜色(并不是所有的行列都要涂,即并非所有的任务都进行或参与排序),任务之间的先后关系是隐含的。

本题要逆向考虑,考虑最后涂的,再向前考虑。建图,所有的行列为点(不考虑不用涂的边和列),如果是s[i][j] 为 ‘O’,则加边G[i].push_back(j),d[j]++, 说明再涂j之前要先涂i。符合拓扑排序的特征。若为‘X’,则加边G[j].push_back(i),d[i]++;

考虑最小序时,每一次取最小的即可。

//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FD(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)

typedef long long LL;
const int INF = 1000000007;
const double eps = 1e-10;
const int MAXN = 1000010;

int n, when;
char s[550][550];
vector<int>G[550 * 2];
int d[550 * 2];
int g[550 * 2];
vector<int>ans;
int allcnt;
void get()
{
    REP(i, n)
    {
        int fla = 0;
        REP(j, n) if (s[i][j] == 'X') fla = 1;
        g[i + n] = fla;
        if (fla) allcnt++;
        fla = 0;
        REP(j, n) if (s[j][i] == 'O') fla = 1;
        g[i] = fla;
        if (fla) allcnt++;
    }
    REP(i, n) REP(j, n)
        {
            int r = i + n;
            int c = j;
            if (!g[r] || !g[c]) continue;
            if (s[i][j] == 'O')
            {
                G[r].push_back(c);
                d[c]++;
            }
            else
            {
                G[c].push_back(r);
                d[r]++;
            }
        }
    REP(i, 2 * n) if (!g[i]) d[i] = -1;
}
bool solve()
{
    while (1)
    {
        int x = -1;
        for (int i = 0; i < 2 * n; i++)
        {
            if (d[i] == 0)
            {
                x = i;
                d[i] = -1;
                break;
            }
        }
        if (x == -1) break;
        ans.push_back(x);
        REP(i, G[x].size())
        {
            d[G[x][i]]--;
        }
    }
    if (ans.size() < allcnt) return false;
    return true;
}
int main ()
{
    int T;
    when = 0;
    RI(T);
    while (T--)
    {
        ans.clear();
        memset(d, 0, sizeof(d));
        memset(g, 0, sizeof(g));
        for (int i = 0; i < n * 2; i++) G[i].clear();
        allcnt = 0;
        RI(n);
        REP(i, n) RS(s[i]);
        get();
        if (!solve()) puts("No solution");
        else
        {
            for (int i = 0; i < ans.size(); i++)
            {
                if (i) printf(" ");
                if (ans[i] < n) printf("C"); else printf("R");
                printf("%d", ans[i] % n + 1);
            }
        puts("");
        }
    }

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