uva1423 拓扑排序

来源:互联网 发布:和msqrd差不多的软件 编辑:程序博客网 时间:2024/06/08 14:37

对于一个序列a1,a2,a3,….an,我们可以计算出一个符号矩阵S,就是上面右图矩阵,其中S(i,j)表示 ai+…+aj的正负号,给出序列不难求出矩阵,我们的任务是求出“逆问题”,即给出矩阵,求出序列,序列每个值大于-10小于10;s[i][j]数组表示表示第i项到第j项的和,如果是“+”则sum[j]-sum[i-1]>0,从j指向i-1,否则当sum[i-1]-sum[j]>0,从i-1指向j

#include <iostream>#include <string.h>#include <queue>using namespace std;bool vis[205];int head[205],degree[205];int cnt,num,n,t;int a[205],sum[205];string s;//第一次用stringstruct edgenode{    int to,next;} edge[205];void init(){    cnt=0;    memset(vis,false,sizeof(vis));    memset(head,-1,sizeof(head));    memset(degree,0,sizeof(degree));    for(int i=0;i<=n;i++)        sum[i]=10;//因为数不超过10,所以最大就是10}void add(int u,int v){    degree[v]++;    edge[cnt].to=v;    edge[cnt].next=head[u];    head[u]=cnt++;}void topu(int n)//拓扑排序模板{    queue<int>q;    num=0;    for(int i=0;i<=n;i++)//这里要从0开始,增加了一个点0,也要进队列·,因为这里我们会要用到sum[0],否则如果       // 0不进队列的话,没法算出sum[0]的值    {        if(!degree[i]&&!vis[i])            {                q.push(i);                vis[i]=1;            }    }    while(!q.empty())    {        int u=q.front();        q.pop();        for(int k=head[u];k!=-1;k=edge[k].next)        {            degree[edge[k].to]--;            sum[edge[k].to]=sum[u]-1;            if(!degree[edge[k].to])                {                    q.push(edge[k].to);                    vis[edge[k].to]=1;                }        }    }}int main(){    cin>>t;    while(t--)    {        init();        memset(a,0,sizeof(a));        cin>>n;        cin>>s;        int k=0;        for(int i=1;i<=n;i++)            for(int j=i;j<=n;j++)        {            if(s[k]=='+')                add(j,i-1);            else if(s[k]=='-')                add(i-1,j);                k++;        }        topu(n);        for(int i=1;i<=n;i++)            a[i]=sum[i]-sum[i-1];       for(int i=1;i<n;i++)        cout<<a[i]<<" ";       cout<<a[n]<<endl;    }    return 0;}
0 0
原创粉丝点击