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
  • 相关阅读:
    LeetCode 1110. Delete Nodes And Return Forest
    LeetCode 473. Matchsticks to Square
    LeetCode 886. Possible Bipartition
    LeetCode 737. Sentence Similarity II
    LeetCode 734. Sentence Similarity
    LeetCode 491. Increasing Subsequences
    LeetCode 1020. Number of Enclaves
    LeetCode 531. Lonely Pixel I
    LeetCode 1091. Shortest Path in Binary Matrix
    LeetCode 590. N-ary Tree Postorder Traversal
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4797631.html
Copyright © 2011-2022 走看看