首页 > 其他 > 详细

Guess

时间:2014-03-24 20:04:54      阅读:568      评论:0      收藏:0      [点我收藏+]

题目链接

  • 题意:
    n个数,给出所有区间的和的正负(-、+、0),求出一种可能的序列
  • 思路:
    题目中给出了很多偏序关系,求具体的序列(一种即可)。假如知道了所有元素的大小关系(全序关系)就可以构造出这样的序列。也就是说,给定了偏序关系,求一个满足这个偏序关系的全序序列,也就是拓扑排序了。
  • 关键:
    连续和转化为前缀和,就可以得到很多前缀和的大小关系,用小于(或者大于)关系来构图
    对等于关系的处理:相同的元素就加入图中一次,最后更新
const int MAXV = 15;
struct DSU
{
    int father[MAXV];
    void init()
    {
        REP(i, MAXV) father[i] = i;
    }
    int find(int n)
    {
        return father[n] == n ? n : father[n] = find(father[n]);
    }
    void merge(int a, int b)
    {
        int fa = find(a), fb = find(b);
        father[fa] = fb;
    }
} dsu;

struct Graph
{
    typedef pair<int, int> pii;
    queue<int> q;
    vector<int> vt[MAXV];
    int in[MAXV], sum[MAXV];
    bool vis[MAXV][MAXV];
    void init()
    {
        REP(i, MAXV)
            vt[i].clear();
        while (!q.empty())
            q.pop();
        CLR(in, 0);
        CLR(sum, 0);
        CLR(vis, false);
    }
    void add(int a, int b)
    {
        if (vis[a][b]) return;
        vt[a].push_back(b);
        vis[a][b] = true;
        in[b]++;
    }
    void solve(int n)
    {
        CLR(vis, 0);
        FE(i, 0, n)
            if (in[i] == 0)
                q.push(i);
        int k = 0;
        while (!q.empty())
        {
            int t = q.front();
            q.pop();
            int len = vt[t].size();
            sum[t] = k++;
            REP(i, len)
            {
                int next = vt[t][i];
                if (!vis[t][next])
                {
                    vis[t][next] = true;
                    if (--in[next] == 0)
                        q.push(next);
                }
            }
        }
        FE(i, 0, n)
            sum[i] = sum[dsu.find(i)];
        printf("%d", sum[1] - sum[0]);
        FE(i, 2, n)
            printf(" %d", sum[i] - sum[i - 1]);
        puts(" ");
    }
} graph;

char ipt[200];

int main()
{
//    freopen("in.txt", "r", stdin);
    int T, n;
    RI(T);
    FE(kase, 1, T)
    {
        vector<int> vt;
        dsu.init();
        graph.init();
        RI(n);
        RS(ipt);
        int cnt = 0;
        FE(i, 1, n) FE(j, i, n)
        {
            if (ipt[cnt] == ‘0‘)
                dsu.merge(i - 1, j);
            cnt++;
        }
        cnt = 0;
        FE(i, 1, n) FE(j, i, n)
        {
            if (ipt[cnt] == ‘-‘)
                graph.add(dsu.find(j), dsu.find(i - 1));
            else if (ipt[cnt] == ‘+‘)
                graph.add(dsu.find(i - 1), dsu.find(j));
            cnt++;
        }
        graph.solve(n);
    }
    return 0;
}


Guess,布布扣,bubuko.com

Guess

原文:http://blog.csdn.net/wty__/article/details/21975275

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!