[HNOI 2015] 菜肴制作

[题目链接]

       https://www.lydsy.com/JudgeOnline/problem.php?id=4010

[算法]

        建反向图,在反向图上拓扑排序即可,注意用堆代替队列

[代码]

       

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010

struct edge
{
    int to,nxt;
} e[MAXN];

int i,n,m,x,y,T,tot;
int head[MAXN],deg[MAXN];

template <typename T> inline void read(T &x)
{
    int f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar())
    {
        if (c == '-') f = -f;
    }
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}
inline void addedge(int u,int v)
{
    tot++;
    e[tot] = (edge){v,head[u]};
    head[u] = tot;
}
inline void topsort()
{
    int i,v,cnt = 0,cur;
    static int ans[MAXN];
    static priority_queue< int > q;
    while (!q.empty()) q.pop();
    for (i = 1; i <= n; i++) 
    {
        if (!deg[i])
            q.push(i);    
    }    
    while (!q.empty())
    {
        cur = q.top();
        q.pop();
        ans[++cnt] = cur;
        for (i = head[cur]; i; i = e[i].nxt)
        {
            v = e[i].to;
            if (!(--deg[v])) q.push(v);
        }
    }
    if (cnt != n) 
    {
        printf("Impossible!\n");
        return;
    }
    reverse(ans + 1,ans + n + 1);
    for (i = 1; i < n; i++) printf("%d ",ans[i]);
    printf("%d\n",ans[n]);
}

int main()
{
    
    read(T);
    while (T--)
    {
        read(n); read(m);
        tot = 0;
        for (i = 1; i <= n; i++) head[i] = deg[i] = 0;
        for (i = 1; i <= m; i++)
        {
            read(x); read(y);
            addedge(y,x);
            deg[x]++;
        }
        topsort();
    }
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/evenbao/p/9487755.html
今日推荐