【BZOJ】[HNOI2015]菜肴制作

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4010


 

要是考场上想不出,但是还是有一个分治的做法的嘛

 

做法就是反向连边,然后再反向输出字典序最大的拓扑序。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 #include<queue>
 9 using namespace std;
10 #define maxn 1001000
11 #define llg long long 
12 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
13 llg n,m,du[maxn],bj[maxn],dl[maxn],tail,T;
14 vector<llg>a[maxn];
15 
16 struct node
17 {
18     llg po,du;
19     bool operator <(const node&a)const
20     {
21         if (a.du==du) return a.po>po;
22         else return a.du<du;
23     }
24 };
25 
26 priority_queue<node>q;
27 
28 void init()
29 {
30     for (llg i=1;i<=n;i++) a[i].clear(),du[i]=0;
31     cin>>n>>m;
32     for (llg i=1;i<=m;i++)
33     {
34         llg x,y;
35         scanf("%lld%lld",&x,&y);
36         a[y].push_back(x);
37         du[x]++;
38     }
39     while (!q.empty()) q.pop();
40     for (llg i=1;i<=n;i++)
41     {
42         node e;
43         e.po=i;
44         e.du=du[i];
45         q.push(e);
46     }
47 }
48 
49 bool work()
50 {
51     for (llg i=1;i<=n;i++) bj[i]=0;
52     tail=0;
53     while (!q.empty())
54     {
55         node w=q.top();
56         q.pop();
57         if (bj[w.po]) continue;
58         bj[w.po]=1;
59         if (w.du!=0) return 0;
60         dl[++tail]=w.po;
61         llg x=w.po;
62         llg W=a[x].size();
63         for (llg i=0;i<W;i++)
64         {
65             llg v=a[x][i];
66             node e;
67             e.po=v; du[v]--; e.du=du[v];
68             q.push(e);
69         }
70     }
71     return 1;
72 }
73 
74 int main()
75 {
76     yyj("a");
77     cin>>T;
78     while (T--)
79     {
80         init();
81         if (!work()) puts("Impossible!");
82         else 
83         {
84             for (llg i=tail;i>=1;i--) printf("%lld ",dl[i]);
85             printf("\n");
86         }
87     }
88     return 0;
89 }

 

转载于:https://www.cnblogs.com/Dragon-Light/p/6392923.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值