杭電OJ-1285(隊伍排名)

題目鏈接
因爲輸出格式不對錯了幾次,用到了拓撲排序的思路,不過寫本題目的時候最耗時間的是研究自定義優先隊列排序的方法。

#include<iostream>
#include<queue>
#include<functional>
using namespace std;
typedef struct Node
{
    queue<int> list;//記錄後繼結點
    int degree;//記錄入度
    int num;//記錄自己的序號
    int is;//記錄該節點是否已經取出     
}Node;
bool operator > ( Node a,Node b) //這裏的參數如果是Node*    並不知道爲什麼
{
    return a.num > b.num; //自定義排序從小到大
};
int main()
{
    priority_queue<Node,vector<Node>,greater<Node>> queue; //優先隊列
    int n,m;
    int i,j;
    Node a[500];
    int sum = 0;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
    for(int i =0;i<n;i++)
    {
        Node temp = Node(); //創建節點
        temp.degree = 0;//初始化入度爲0
        temp.num = i;//賦值節點序號   代表隊伍代號
        temp.is = 0; //初始化節點未取出
        a[i] = temp; //進入數組
    }
    for(int s=0;s<m;s++)
    {
        scanf("%d %d",&i,&j); //輸入隊伍比賽結果
        a[j-1].degree++; //失敗隊伍入度加1
        a[i-1].list.push(j-1);  //失敗隊伍作爲勝利隊伍的後繼節點添加到勝利隊伍結構體的list裏
    }

    for(int s=0;s<n;s++)//第一次遍歷 找到入度爲0的節點壓入有限隊列  ,爲什麼從小到大排序,因爲題目要求,小序號的隊伍排在前面
    {
        if(a[s].degree == 0)
        {
            a[s].is = 1;  //當前節點取出
            queue.push(a[s]);//入優先隊列

        }
    }

    while(!queue.empty())//當優先隊列不爲空
    {
        while(queue.top().list.size()) //遍歷當前節點的後繼節點
        {
            a[queue.top().list.front()].degree--;//後繼節點入度減1
            queue.top().list.pop();//當前後繼節點出隊列
        }
        if(sum < n-1) //控制輸出格式
        {
        printf("%d ",queue.top().num+1);
        sum++;
        }
        else
        {
            printf("%d\n",queue.top().num+1);
        }

        queue.pop();
        for(int i =0;i<n;i++)  //一次出隊後再次遍歷數組 ,查找當前入度爲0 的節點,繼續入隊列
        {
            if(a[i].degree == 0 && a[i].is == 0) //如果當前節點入度爲0 且此時並未被取出   ,不加這個條件會把已經出優先隊列的節點再進隊列
        {
            a[i].is = 1;  //當前節點取出
            queue.push(a[i]);//進隊列
        }
        }   

    }
            sum = 0;
    }


}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章