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 }
原文出处http://www.cnblogs.com/showson/