祖先們都在看着你

祖先們都在看着你


題目描述

公元前2000年。
在某塊草原中,生活着一羣牛,它們都有着自己的圖騰和信仰。
因此,不同信仰的牛們很自然地分爲了各個部族。
爲了自己所在部族的神靈,牛們經常會發起聖戰,爲神靈奪取地盤。
在很長一段時間內,各個部族的矛盾幾乎到達了不可調和的地步!
這時,在衆牛中,出現了一位豪傑,他在短時間內將各部族拉入麾下,建立起了血蹄部族。
他就是後來爲牛們所傳頌的偉人:孛兒只斤•彰異牛,又名蜃牛•血蹄。
他給牛們帶來了文明。
教會了牛們只用兩個後蹄走路,空出前蹄來工作,以致於出現了後來謙遜而不失高貴,致力於侍奉自然的牛頭人族。
而那片草原正是後來的莫高雷。(求不吐槽……)
牛頭人們的生活不是和平的,它們侍奉自然,對破壞自然平衡、褻瀆大地母親的行爲深惡痛絕,所以,它們有着自己訓練有素的軍隊。孛兒只斤•彰異牛逝世多年後,由於牛頭人們的信仰,它們一直相信祖先彰異牛在看着它們(囧),正因爲如此,它們在軍隊訓練過程中沒有絲毫懈怠。
某天,在彰異牛的注視下,N 個牛頭人(依次標號 1N )加入了軍隊,由某牛頭人隊長帶領。
而軍隊審查了他們的資料後,給出了 M 條指示,第 i 條指示的內容是:第 Ai 號牛頭人必須站在第 Bi 號牛頭人的左邊,指示之間不會出現矛盾。
牛頭人隊長拿到指示後,便開始規劃 N 個牛頭人的列隊方式了。
現在,你需要用計算機的力量秒殺(1s運行時間搞定)牛頭人隊長!


輸入格式

第一行 2 個數字 nM
接下來 M 行,每行兩個數字 AiBi


輸出格式

輸出 N 行,即 N 個牛頭人的站隊序列。
如果有多個站隊序列滿足要求,輸出任意一個即可。


樣例輸入

5 4
1 2
2 3
3 4
4 5


樣例輸出

1
2
3
4
5


樣例解釋

1在2前,2在3前,3在4前,4在5前、只有排列12345滿足要求。


數據範圍

10% 的數據 1N81M28
40% 的數據 1N10001M105
100% 的數據 1N1051M106


Solution

拓撲排序求拓撲序列。


Code

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>

using namespace std;

int n,m,cnt;
int du[100010],head[100010],nxt[1000010],data[1000010];
bool vis[100010];

queue<int>q;

void add(int x,int y){
    nxt[cnt]=head[x];data[cnt]=y;head[x]=cnt++;
}

int main(){
    freopen("ancestors.in","r",stdin);
    freopen("ancestors.out","w",stdout);
    memset(head,-1,sizeof head);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        add(x,y);
        du[y]++;
    }
    for(int i=1;i<=n;i++)if(!du[i])q.push(i);
    while(!q.empty()){
        int now=q.front();
        q.pop();
        if(!vis[now]){
            vis[now]=true;
            printf("%d\n",now);
        }
        for(int i=head[now];i!=-1;i=nxt[i]){
            du[data[i]]--;
            if(!du[data[i]]){
                q.push(data[i]);
            }
        }
    }
    return 0;
}

SPJ

#include <bits/stdc++.h>

typedef long long LL;

#define FOR(i, a, b) for (int i = (a), i##_END_ = (b); i <= i##_END_; i++)
#define DNF(i, a, b) for (int i = (a), i##_END_ = (b); i >= i##_END_; i--)

template <typename Tp> void in(Tp &x) {
    char ch = getchar(), f = 1; x = 0;
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') f = -1, ch = getchar();
    while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    x *= f;
}

template <typename Tp> bool chkmax(Tp &x, Tp y) {return x > y ? 0 : (x=y,1);}
template <typename Tp> bool chkmin(Tp &x, Tp y) {return x < y ? 0 : (x=y,1);}
template <typename Tp> Tp Max(Tp x, Tp y) {return x > y ? x : y;}
template <typename Tp> Tp Min(Tp x, Tp y) {return x < y ? x : y;}

const int MAXM = 1000010;

int n, m;
int A[MAXM], B[MAXM];

int ans[MAXM], pos[MAXM];

int main(int argc, char **argv) {
    FILE *fdata = fopen(argv[1], "r");
    FILE *fsource = fopen(argv[2], "r");
    FILE *fscore = fopen(argv[5], "w");
    FILE *ffull = fopen(argv[4], "r");
    fscanf(fdata, "%d%d", &n, &m);
    FOR(i, 1, m) fscanf(fdata, "%d%d", &A[i], &B[i]);
    FOR(i, 1, n) {
        int x;
        fscanf(fsource, "%d", &x);
        pos[x] = i;
    }
    FOR(i, 1, m) if (pos[A[i]] >= pos[B[i]]) {
        fprintf(fscore, "0");
        return 0;
    }
    int full_score;
    fscanf(ffull, "%d", &full_score);
    fprintf(fscore, "%d", full_score);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章