「HNOI2015」菜肴制作
「HNOI2015」菜肴制作
这道题想到了其实还挺水的,一开始我直接用小根堆拓扑然后就爆0了,然后我又用十万个堆搜索,T30,还是xkl告诉我要倒着拓扑。
首先要建反图,对于入度为0的点,较小的点先输出所以要优先拓扑大的点,这样就保证了大的点及其子树(其实并不是树,这样好理解点)都存在数组前面,再倒着输出即可。
#include<iostream> #include<cstring> #include<cstdio> #include<time.h> #include<queue> #define ma(x) memset(x,0,sizeof(x)) using namespace std; struct edge { int u,v,nxt; #define u(x) ed[x].u #define v(x) ed[x].v #define n(x) ed[x].nxt }ed[100010]; int first[100010],num_e=1; #define f(x) first[x] int d; int n,m,du[100010],ans[100010],cnt; bool v[100010]; inline void add(int u,int v) { ++num_e; u(num_e)=u; v(num_e)=v; n(num_e)=f(u); f(u)=num_e; } bool ved[100010],ving[100010]; signed main() { // freopen("in.txt","r",stdin); // freopen("4.in","r",stdin); // freopen("1.out","w",stdout); cin>>d; while(d--) { ma(ed);ma(first);ma(du);ma(ans);ma(v); cnt=0;num_e=1; scanf("%d%d",&n,&m); int a,b; for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); add(b,a); du[a]++; } priority_queue<int> q; for(int i=1;i<=n;i++) if(!du[i]){v[i]=1;q.push(i);} if(q.empty()){puts("Impossible!");continue;} while(q.size()) { int k=q.top();q.pop(); ans[++cnt]=k; for(int i=f(k);i;i=n(i)) if(!v[v(i)]) { du[v(i)]--; if(!du[v(i)]) { v[v(i)]=1; q.push(v(i)); } } } if(cnt!=n){puts("Impossible!");continue;} for(int i=cnt;i;i--) printf("%d ",ans[i]);puts(""); } }
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<queue> 5 #define ma(x) memset(x,0,sizeof(x)) 6 using namespace std; 7 struct edge 8 { 9 int u,v,nxt; 10 #define u(x) ed[x].u 11 #define v(x) ed[x].v 12 #define n(x) ed[x].nxt 13 }ed[100010]; 14 int first[100010],num_e=1; 15 #define f(x) first[x] 16 int d; 17 int n,m,du[100010],ans[100010],cnt; 18 bool v[100010]; 19 int minn[100010]; 20 bool pd=0; 21 inline void add(int u,int v) 22 { 23 ++num_e; 24 u(num_e)=u; 25 v(num_e)=v; 26 n(num_e)=f(u); 27 f(u)=num_e; 28 } 29 priority_queue<int,vector<int>,greater<int> >q[100010],temm; 30 void dfs1(int x,int fa) 31 { 32 v[x]=1;q[x].push(x); 33 for(int i=f(x);i;i=n(i)) 34 if(v(i)!=fa) 35 { 36 if(!v[v(i)])dfs1(v(i),x); 37 temm=q[v(i)]; 38 while(temm.size()) 39 { 40 q[x].push(temm.top()); 41 temm.pop(); 42 } 43 } 44 } 45 bool ved[100010],ving[100010]; 46 void dfs2(int x) 47 { 48 // cout<<x<<endl; 49 if(pd)return; 50 ving[x]=1; 51 // cout<<q[x].size()<<endl; 52 // while(!q[x].empty()&&q[x].top()==x)q[x].pop(); 53 // cout<<q[x].size()<<endl; 54 while(q[x].size()) 55 { 56 while(!q[x].empty()&&q[x].top()==x)q[x].pop(); 57 if(q[x].empty())break; 58 int k=q[x].top();q[x].pop(); 59 // cout<<k<<endl; 60 if(ving[k]){pd=1;return;} 61 if(!ved[k])dfs2(k); 62 } 63 ving[x]=0;ved[x]=1; 64 ans[++cnt]=x; 65 } 66 signed main() 67 { 68 // freopen("in.txt","r",stdin); 69 // freopen("1.in","r",stdin); 70 // freopen("1.out","w",stdout); 71 72 cin>>d; 73 while(d--) 74 { 75 ma(ed);ma(first);ma(du);ma(ans);ma(v);ma(minn);ma(q);ma(ving);ma(ved); 76 pd=cnt=0;num_e=1; 77 scanf("%d%d",&n,&m); 78 int a,b; 79 for(int i=1;i<=m;i++) 80 { 81 scanf("%d%d",&a,&b); 82 add(b,a); 83 du[b]++; 84 } 85 for(int i=1;i<=n;i++) 86 if(!v[i])dfs1(i,0); 87 for(int i=1;i<=n;i++) 88 if(!ved[i])dfs2(i); 89 /* for(int i=1;i<=n;i++) 90 { 91 printf("#%d:\n",i); 92 while(q[i].size()) 93 { 94 cout<<q[i].top()<<endl; 95 q[i].pop(); 96 } 97 }*/ 98 99 if(pd){puts("Impossible!");continue;} 100 for(int i=1;i<=cnt;i++) 101 printf("%d ",ans[i]);puts(""); 102 } 103 }
波澜前,面不惊。