题解 P3243 【[HNOI2015]菜肴制作】

这道题看起来就是个裸的拓扑排序,抄上模板就能AC。

上面这种想法一看就不现实,然鹅我第一次还真就这么写了,然后被随意hack。


我们需要注意一句话:

现在,酒店希望能求出一个最优的菜肴的制作顺序,使得小 A能尽量先吃到质量高的菜肴:

这句话什么意思呢?

看上去它是说想要一个字典序最小的排列,但我们可以发现,题目并不是强求质量高一定先,而是有一个宽限范围(可能我讲的比较玄学)。

解决方案是贪心地把大的放在末尾,那么最后一定是最优解。

所以我们跑一个字典序最大的拓扑就可以了。

字典序最大就是反着跑一遍字典序最小。


AC代码如下:

820ms 133668kb

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 namespace StandardIO {
 6 
 7     template<typename T>inline void read (T &x) {
 8         x=0;T f=1;char c=getchar();
 9         for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
10         for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
11         x*=f;
12     }
13 
14     template<typename T>inline void write (T x) {
15         if (x<0) putchar('-'),x*=-1;
16         if (x>=10) write(x/10);
17         putchar(x%10+'0');
18     }
19 
20 }
21 
22 using namespace StandardIO;
23 
24 namespace Solve {
25         
26     const int N=300300;
27     
28     int T,n,m,cnt;
29     int indeg[N],ans[N];
30     vector<int>graph[N];
31     
32     inline void toposort () {
33         int temp[N];
34         priority_queue<int>q;
35         memcpy(temp,indeg,sizeof(indeg));
36         while(!q.empty())q.pop();
37         for (register int i=1; i<=n; ++i) {
38             if (temp[i]==0) q.push(i);
39         }
40         while (!q.empty()) {
41             int v=q.top();q.pop();
42             ans[++cnt]=v;
43             for (register int i=0; i<graph[v].size(); ++i) {
44                 int to=graph[v][i];
45                 temp[to]--;
46                 if (temp[to]==0) q.push(to);
47             }
48         }
49     }
50     
51     inline void solve () {
52         read(T);
53         while (T--) {
54             read(n),read(m);
55             cnt=0,memset(indeg,0,sizeof(indeg));
56             for (register int i=1; i<=n; ++i) {
57                 graph[i].clear();
58             }
59             for (register int i=1; i<=m; ++i) {
60                 int x,y;
61                 read(x),read(y);
62                 indeg[x]++;
63                 graph[y].push_back(x);
64             }
65             toposort();
66             if (cnt!=n) puts("Impossible!");
67             else {
68                 for (register int i=n; i>=1; --i) write(ans[i]),putchar(' ');
69                 putchar('\n');
70             }
71         }
72         
73     }
74 }
75 
76 using namespace Solve;
77 
78 int main () {
79 //    freopen(".in","r",stdin);
80 //    freopen(".out","w",stdout);
81     solve();
82 }

猜你喜欢

转载自www.cnblogs.com/ilverene/p/9841096.html
今日推荐