zoukankan      html  css  js  c++  java
  • uva1423 巧用拓扑排序

    对于一个序列 a1 a2 ... an 我们可以计算出一个符号矩阵A, 其中Si,j 为 a1+...+aj 的正负号,(连加和大于0则Sij=+ 小于0 Sij=-  等于0 则Sij=0), 根据序列A不难算出上述符号矩阵。你的任务是求解它的“逆问题” , 及给出一个符号矩阵,找出一个对应的序列。输入保证存在一个满足条件的序列,其中每个整数的绝对值均不超过10

    解  连续和转化为前缀和之差,设Bi=a1+...+ai 规定B0=0 则矩阵中的任意一项都等价于连个Bi 相减之后的正负号,例如 , 第x行y列的符号为正号 ax+...+ay>0 By-Bx-1>0, 转化为已知B0,B1,...,Bn,的一些大小关系,求他们的值,这个问题通过拓扑排序完成。

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include<vector>
    #include <algorithm>
    using namespace std;
    const int INF=50;
    char str[150];
    vector<int> same[15];
    vector<int> to[15];
    int dgreed[15];
    int G[15];
    bool use[15];
    int ans[15];
    void solve(int loc, int v){
        for(int i=0; i<same[loc].size(); ++i)
             ans[ same[loc][i] ]=v;
    }
    int main()
    {
         int cas;
         scanf("%d",&cas);
         for(int cc=1; cc<=cas; ++cc){
             int n;
             scanf("%d",&n);
             scanf("%s",str);
             int loc=0;
             memset(dgreed,0,sizeof(dgreed));
             memset(use,false,sizeof(use));
             for(int i=0; i<=n; ++i) to[i].clear(),ans[i]=INF,same[i].clear();
             for(int i=1; i<=n; ++i)
                 for(int j=i; j<=n; ++j ){
                     if(str[loc]=='0'){
                         same[i-1].push_back(j);
                         same[j].push_back(i-1);
                     }else if(str[loc]=='+'){
                         to[i-1].push_back(j);
                         dgreed[j]++;
                     }else {
                         to[j].push_back(i-1);
                         dgreed[i-1]++;
                     }
                     loc++;
                 }
              for(int i=0; i<n+1;++i){
                    int k=0;
                  for(int j=0; j<n+1; ++j)
                    if(use[j]==false&&dgreed[j]==0){
                         k=j; break;
                    }
                G[i]=k; use[k]=true;
                for(int j=0; j<to[k].size(); ++j){
                      dgreed[to[k][j]]--;
                }
              }
            loc=0;
            for(int i=0; i<n+1; ++i)
            if(G[i]==0) {
                    loc=i; break;
            }
            ans[0]=0;
            int v=-1;
            solve(0,0);
            for(int i=loc-1; i>=0; --i){
                  if(ans[ G[i] ] == INF){
                     ans[ G[i] ] =v--;
                  }
                  solve(G[i],ans[G[i]]);
            }
            v=1;
            for(int i=loc+1; i<=n; ++i){
                  if(ans[ G[i] ] == INF){
                     ans[ G[i] ] =v++;
                  }
                  solve(G[i],ans[G[i]]);
            }
            for(int i=1; i<=n ;++i)
                 printf("%d%c",ans[i]-ans[i-1],i==n?'
    ':' ');
         }
        return 0;
    }
    View Code
  • 相关阅读:
    操作系统
    OSI协议
    5、hadoop常见端口汇总
    20、Linux 常用命令ll失效
    java 图形化工具Swing 监听键盘输入字符触发动作getInputMap();getActionMap();
    java 图形化工具Swing 基本使用
    java 图形化小工具Abstract Window Toolit ImageIO缩放图片,添加水印
    java 图形化小工具Abstract Window Toolit 画笔 处理位图
    java 图形化小工具Abstract Window Toolit :画笔Graphics,画布Canvas(),弹球小游戏
    java 图形化小工具Abstract Window Toolit 菜单项
  • 原文地址:https://www.cnblogs.com/Opaser/p/4284213.html
Copyright © 2011-2022 走看看