HDU

来源:互联网 发布:怎样推广淘宝网店 编辑:程序博客网 时间:2024/06/01 09:06

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857

题目大意:在满足先后顺序的前提下,让号码小的尽量在前

解题思路:一开始想到了一定是取出最小的然后依次拓扑下去,后来找了个反例5->1,3->2,正确顺序应该是5,1,3,2。那么如何解决这个问题呢,我们发现,首先要找出最小的数字所在的位置,把他们放到最前面,之后找次小的放在次前面,那么反过来就是最大的放到最后面,通过反向的拓扑排序,把最大的先取出来即可。

参考博客:http://blog.csdn.net/u012861385/article/details/38059515

AC代码:

#include<cstdio>#include<cstring>#include<queue>using namespace std;const int MAXN = 30000 + 5;const int MAXM = 100000 + 5;struct Edge{    int v, next;    Edge(int v=0,int next=0):v(v),next(next){}}edge[MAXM];int head[MAXN],edgnum;int indegr[MAXN];int ans[MAXN], tot;void toInit(){    memset(head, -1, sizeof(head));    memset(indegr, 0, sizeof(indegr));    edgnum = 0;    tot = 0;}void toAdd(int u,int v){    edge[edgnum] = Edge(v, head[u]);    head[u] = edgnum++;}void toBfs(int n){    priority_queue<int> qi;    for (int i = 1;i <= n;++i)        if (!indegr[i])            qi.push(i);    while (!qi.empty())    {        int u = qi.top();qi.pop();        ans[tot++] = u;        for (int i = head[u];i != -1;i = edge[i].next)        {            int v = edge[i].v;            indegr[v]--;            if (!indegr[v])                qi.push(v);        }    }}int main(){    int t;scanf("%d", &t);    while (t--)    {        int n, m;        scanf("%d%d", &n, &m);        toInit();        for (int i = 1;i <= m;++i)        {            int u, v;            scanf("%d%d", &v, &u);            toAdd(u, v);            indegr[v]++;        }        toBfs(n);        for (int i = tot - 1;i > 0;--i)            printf("%d ", ans[i]);        printf("%d\n", ans[0]);    }    return 0;}
原创粉丝点击