UVa Live4255

原创 2016年08月28日 20:05:39

第一个有关拓扑排序的题目,光看题目很难想到这题是拿topo来做的。看了白书上的分析才知道拿topo来做,并且也用到了常用的连续和转化为前缀和之差的思想,然后奖前缀和标号作为图的结点利用大小+-来进行连接即可。然后由得大小关系的原因所建成的图,所以 每一层的topo得到可以入队列的入度为0的结点的时候,都可以将该结点进行赋值,然后最外层的肯定是最大值,每一层减一即可。这样做的话就不需要再让pre[0]=0了,因为0也是图内 的结点,也会得到一个确定的f值,然后就可以得到每个值了。一开始自己写的,写了一堆乱糟糟的虽然过样例还是WA的渣代码,参考这篇博文

http://blog.csdn.net/houserabbit/article/details/38929571   点击打开链接

#include<cstdio>
#include<cstring>
#include<algorithm>


using namespace std;

int t,n;
char m[15][15];
int a[15],pre[20];

struct Edge
{
    int v,nexts;
}edge[60];
int head[20],indegree[20],vis[20];
int cnt,q[20],num;

void add_edge(int u,int v)
{
    Edge p;
    p.v=v;
    p.nexts=head[u];
    edge[cnt]=p;
    head[u]=cnt++;
}

void topsort()
{
    int f=10;
    num=0;
    for(int i=0;i<=n;i++)
    {
        if(!indegree[i])
        {
            q[num++]=i;
            pre[i]=f;
        }
    }
    f--;
     for(int i=0;i<num;i++)
     {
          vis[q[i]]=1;
         for(int k=head[q[i]];k!=-1;k=edge[k].nexts)
         {
             if(!vis[edge[k].v])
            indegree[edge[k].v]--;
            if(!indegree[edge[k].v])
            {
                q[num++]=edge[k].v;
                pre[edge[k].v]=f;
            }
         }
         f--;
     }
}

void init()
{
         int k=0;
    char s[60];
       scanf("%d",&n);
       scanf("%s",s);

    for(int i=1;i<=n;i++)
       {
           for(int j=i;j<=n;j++)
           {
               m[i][j]=s[k++];
               if(m[i][j]=='+')
               {
                   indegree[i-1]++;
                   add_edge(j,i-1);
               }
               else if(m[i][j]=='-')
               {
                   indegree[j]++;
                   add_edge(i-1,j);
               }
          }
    }

}


int main()
{
   scanf("%d",&t);
   while(t--)
   {
       cnt=0;
       memset(head,-1,sizeof(head));
    memset(indegree,0,sizeof(indegree));
    memset(vis,0,sizeof(vis));
         init();
        topsort();
   for(int i=1;i<=n;i++)
   {
       printf("%d%s",pre[i]-pre[i-1],(i==n)?"\n":" ");
   }
}
  return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

uva La 4255 Guess (拓扑排列)

uva La 4255 Guess (拓扑排列) 拓扑排列适用于DAG有向无环图。 构造所有节点之间的单向边。 具体问题中,抽象出点和边(单向边),单向边对应于具体的点之间的大小关系或需求关。 ...
  • guognib
  • guognib
  • 2014年03月21日 12:08
  • 872

UVa live3415Guardian of Decency(二分最大匹配之最大独立点集)

题目地址:

UVa live6492Welcome Party(二分最大匹配之最小点覆盖)

题目地址:

uva live4731 蜂窝网络 题解(dp+贪心)

题意是:  手机在蜂窝网络中的定位是一个基本问题。假设蜂窝网络已经得知手机处于c1, c2,…,cn这些区域中的一个,最简单的方法是同时在这些区域中寻找手机。但这样做很浪费带宽。由于蜂窝网络中...

UVA live2322

题目的意思就是有n个木棍,给出没跟木棍的长度和zhongl

UVa 10716 - Evil Straw Warts Live

题意:判断一个字符串是否能转化成回文串,如果可以就统计转化成回文串所需的最少交换次数。 贪心,思路就是先将串两端固定(对应字母移至对应位置),依次向中间夹逼,因为只有依次将字母先放到两端,才可以减少...

UVa Live Archive 2322 - Wooden Sticks

传送门UVa Live Archive 2322 - Wooden Sticks 题意:给出木棍的长和宽,如果后一根制造的木棍...

UVA live - 4327(滑动队列优化dp)

方法同上题, 对于每一层而言 d[ i ][ j ] 的最优解为max(d[I-1 ][j] , L(I,j),R(i,j)); 其中L(i,j)代表从i,j往左走若干位置的最优解。 在这里只讨...

UVA Live 6122 || UESTC OJ 2326 枚举+排序+LIS

传送门: UVALive UESTC OJ 题意:有n个盒子,知道长宽高,将盒子堆起来,盒子可任意翻转,顺序任意,要求上面盒子的底面不能超出下面盒子的底面,问最多能堆多少个。 思路:首先n ...

uva live 3882 And Then There Was One 约瑟夫环

// uva live 3882 And Then There Was One // // 经典约瑟夫环问题。n是规模,k是每次数的人数,m是第一个出列的人。 // // 但是暴力用链表做肯定是不行的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UVa Live4255
举报原因:
原因补充:

(最多只允许输入30个字)