【拓扑排序】MicroRNA Ranking

本文介绍了一种用于生物信息学的算法,旨在寻找与特定人类健康因素相关的微RNA。通过设计多个微RNA排序算法,从不同角度评估微RNA的相关性,并提出一种方法来找到这些算法的共识排名。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
Ahlaam is a computer science student, doing her master thesis on a bioinformatics project about MicroRNAs, special molecule types found in cells. During her thesis, she wants to find microRNAs relevant to a specific health factor in human beings.
Ahlaam has designed k microRNA ranking algorithms, each of which ranks microRNAs from a specific point of view.
There are n microRNAs numbered 1 through n, and each algorithm produces one permutation of these n microRNAs. In the permutation produced by each algorithm, the first microRNA is inferred by the algorithm as the most relevant one to the health factor, and the last microRNA is inferred as the least relevant one. 
Ahlaam wants to report a consensus ranking on microRNAs. In a consensus ranking, if microRNA i is ranked before another mircroRNA j, then at least half of the algorithms should have ranked i before j. Write a program to help Ahlaam find a consensus ranking.

 

输入
There are multiple test cases in the input. The first line of each test contains two space-separated integers n (1 ⩽ n ⩽ 1000) and k (1 ⩽ k ⩽ 200), the number of microRNAs and the number of ranking algorithms, respectively. Then, there are k lines, where the i-th line contains a permutation of n numbers 1, . . . , n, representing the output of the i-th ranking algorithm. The input terminates with a line containing 0 0 which should not be processed.

 

输出
For each test case, print a single line containing a permutation of n numbers 1, . . . , n, representing a possible consensus ranking. If there are more than one correct consensus rankings, print the first one in lexicographic order (a sequence a1 , . . . , an is lexicographically less than a sequence b1 , . . . , bn iff there exists a positive integer j such that ai = bi for all 1 ⩽ i ⩽ j   1 and aj < bj ) . If no such a ranking exists, write “No solution” instead.

 

样例输入
5 3
3 2 4 1 5
4 1 5 2 3
2 4 5 1 3
5 2
5 4 3 2 1
1 2 3 4 5
4 3
1 4 2 3
4 2 3 1
3 1 2 4
0 0

 

样例输出
2 4 1 5 3
1 2 3 4 5
No solution
思路:

  首先,求出各个数的相对位置,然后将相对位置如dp[i][j],理解为i是j的前置,显然就是拓扑排序,但是我训练的数组开小了,不明白啊,我明明特意开大了呀,又坑队友了

代码如下:
  1 #include <iostream>
  2 #include <bits/stdc++.h>
  3 using namespace std;
  4 const int maxn = 1e3+50;
  5 vector<int> vec[maxn];
  6 int n,k,num=0;
  7 int indeg[maxn];
  8 int dp[250][1050];
  9 int a[1050];
 10 int b[1050];
 11 priority_queue<int,vector<int>,greater<int> > q;
 12 void init()
 13 {
 14     memset(dp,0,sizeof(dp));
 15     memset(indeg,0,sizeof(indeg));
 16     for(int i=1;i<=n;i++)
 17     {
 18         vec[i].clear();
 19     }
 20 }
 21 void build()
 22 {
 23     for(int i=1;i<=n;i++)
 24     {
 25         for(int j=i+1;j<=n;j++)
 26         {
 27             if(dp[i][j]>dp[j][i])
 28             {
 29                 vec[i].push_back(j);
 30                 indeg[j]++;
 31             }
 32             if(dp[j][i]>dp[i][j])
 33             {
 34                 vec[j].push_back(i);
 35                 indeg[i]++;
 36             }
 37         }
 38     }
 39 }
 40 bool topsort()
 41 {
 42     while(!q.empty())
 43         q.pop();
 44     num=0;
 45     for(int i=1;i<=n;i++){
 46         if(!indeg[i]){
 47             q.push(i);
 48         }
 49     }
 50     while(!q.empty())
 51     {
 52         int now=q.top();
 53         q.pop();
 54         b[num]=now;
 55         num++;
 56         for(int i=0;i<vec[now].size();i++)
 57         {
 58             indeg[vec[now][i]]--;
 59             if(indeg[vec[now][i]]==0)
 60                 q.push(vec[now][i]);
 61         }
 62     }
 63     if(num==n)
 64         return true;
 65     else
 66         return false;
 67 }
 68 void judge()
 69 {
 70     if(topsort())
 71     {
 72         for(int i=0;i<n;i++)
 73         {
 74             if(i)
 75                 printf(" ");
 76             printf("%d",b[i]);
 77         }
 78         printf("\n");
 79     }
 80     else
 81     {
 82         printf("No solution\n");
 83     }
 84 }
 85 int main()
 86 {
 87     while(scanf("%d %d",&n,&k)!=EOF&&n&&k)
 88     {
 89         init();
 90         for(int i=1;i<=k;i++)
 91         {
 92             for(int j=1;j<=n;j++)
 93             {
 94                 scanf("%d",&a[j]);
 95             }
 96             for(int j=1;j<=n;j++)
 97             {
 98                 for(int q=j+1;q<=n;q++)
 99                 {
100                     dp[a[j]][a[q]]++;
101                 }
102             }
103         }
104         build();
105         judge();
106     }
107     return 0;
108 }
View Code

 

转载于:https://www.cnblogs.com/SoulSecret/p/9601501.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值