zoukankan      html  css  js  c++  java
  • poj3687 拓扑序

    题意:有编号 1~n 的球,每个球的质量不同,质量从 1 到 n 不等,给出一系列比较,分别是两个编号的球的大小关系,求一个序列满足上述关系,并且从编号 1 开始依次选择可选的最小质量,输出每个球的质量。

    一开始以为就是排好拓扑序之后输出就行了,但这样是按质量从小到大输出的,事实上要输出编号从小到大的球的质量,因此其实是要输出每个球在序列中的位置。改了之后用优先队列从小到大直接做还是 WA 的,之后发现因为前面的优先放置哪个会影响后面小编号的位置,比如 3号<1号 ,2号无比较关系,就会使优先队列先出 2号,再出 3号,最后出 1号,那么 1号的质量就变成最大的了,但事实上,可以 3号最小,1号其次,2号最大,这样 1号的质量就比之前的序列小了,所以我们需要按 1号>3号来建边,然后优先队列先出编号大的,这样就能使编号小的在这一层里最晚出,也就是最轻。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<queue>
     4 #include<vector>
     5 using namespace std;
     6 
     7 int id[205],ma[205][205],n,ans[205],ans1[205];
     8 
     9 bool topo(){
    10     priority_queue<int>q;
    11     for(int i=1;i<=n;++i)if(!id[i])q.push(i);
    12     int cnt=0;
    13     while(!q.empty()){
    14         int u=q.top();
    15         q.pop();
    16         ans[++cnt]=u;
    17         for(int i=1;i<=n;++i){
    18             if(i!=u&&ma[u][i]){
    19                 id[i]--;
    20                 if(!id[i])q.push(i);
    21             }
    22         }
    23     }
    24     if(cnt==n)return 1;
    25     return 0;
    26 }
    27 
    28 int main(){
    29     int T;
    30     scanf("%d",&T);
    31     while(T--){
    32         int m;
    33         scanf("%d%d",&n,&m);
    34         memset(ma,0,sizeof(ma));
    35         memset(id,0,sizeof(id));
    36         bool f=1;
    37         while(m--){
    38             int a,b;
    39             scanf("%d%d",&a,&b);
    40             if(a==b)f=0;
    41             else if(!ma[b][a]){
    42                 ma[b][a]=1;
    43                 id[a]++;
    44             }
    45         }
    46         if(!f)printf("-1
    ");
    47         else{
    48             if(!topo())printf("-1
    ");
    49             else{
    50                 for(int i=1;i<=n;++i){
    51                     ans1[ans[i]]=n-i+1;
    52                 }
    53                 for(int i=1;i<=n;++i){
    54                     printf("%d",ans1[i]);
    55                     if(i==n)printf("
    ");
    56                     else printf(" ");
    57                 }
    58             }
    59         }
    60     }
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    内联元素间的间隔
    事件处理程序DOM0,DOM2,IE的区别总结
    open live writer下载安装
    sublime3下载安装及常用插件、浏览器预览设置
    常用的清除浮动的方法
    input中的name,value以及label中的for
    利用fiddler将本地网页放到某个域下
    Date类型常用概念及方法总结(1)
    构建之法 第六章 敏捷流程
    javascript 入门之 新窗口打开网站
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4797631.html
Copyright © 2011-2022 走看看