bzoj4010: [HNOI2015]菜肴制作

做法是求逆拓扑序中字典序最大的将其反转则得到答案,粗略理解为对于每个数,把能把比大的能够放在他右边的都放在了右边,所以答案最优。

留坑在此

数据太水第一次du没清零都过了?

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cstdio>
 5 #include<algorithm>
 6 #include<vector>
 7 
 8 using namespace std;
 9 
10 const int Maxn=100010,Maxm=100010;
11 
12 int n,m,du[Maxn];
13 
14 struct Edge{
15     int to;
16     Edge*next;
17     Edge(int to=0,Edge*next=0) :to(to),next(next) {}
18 }pool[Maxm],*pis=pool,*fir[Maxn];
19 
20 void AddEdge(int from,int to) {
21     *pis=Edge(to,fir[from]);fir[from]=pis++;
22     du[to]++;
23 }
24 
25 int ans[Maxn],tot;
26 
27 void init() {
28     scanf("%d%d",&n,&m);
29     for(int i=1;i<=n;i++) fir[i]=du[i]=0;
30     tot=0;pis=pool;
31     for(int u,v,i=1;i<=m;i++) {
32         scanf("%d%d",&u,&v);
33         AddEdge(v,u);
34     }
35 }
36 
37 #include<queue>
38 priority_queue<int,vector<int>,less<int> >q;
39 
40 void work() {
41     
42     for(int i=1;i<=n;i++) {
43         if(du[i]==0) q.push(i);
44     }
45     for(int x;!q.empty();) {
46         x=q.top();q.pop();
47         ans[++tot] = x;
48         for(Edge*p=fir[x];p;p=p->next) {
49             if(!--du[p->to]) q.push(p->to);
50         }
51     }
52         
53     if(tot!=n) printf("Impossible!");
54     else for(int i=n;i;i--) {
55         printf("%d ",ans[i]);
56     }puts("");
57 }
58 
59 int main() {
60 
61     int T;
62     for(scanf("%d",&T);T--;) {
63         init();
64         work();
65     }
66     
67     return 0;
68 }

 

posted @ 2015-07-29 21:19  Showson  阅读(143)  评论(0编辑  收藏  举报