1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| #include <iostream> #include <cstdio> #include <climits> #include <cstring> #include <queue> using namespace std; const int Mn(10050),Mm(100050); inline int _min(int x,int y) { return x<y ? x : y; } struct edge { int s,e,cp,nt; }ed[Mm<<1]; int vs[Mn],ec(-1); void adde(int s,int e) { ed[++ec].s=s, ed[ec].e=e, ed[ec].cp=1; ed[ec].nt=vs[s]; vs[s]=ec; ed[++ec].s=e, ed[ec].e=s, ed[ec].cp=0; ed[ec].nt=vs[e]; vs[e]=ec; }
int d[Mn],p[Mn]; bool bfs() { memset(d,0,sizeof d); queue<int> q; q.push(0); d[0] = 1; while(!q.empty()) { int x(q.front()); q.pop(); for(int i(vs[x]);i!=-1;i=ed[i].nt) { edge& e(ed[i]); if(!d[e.e] && e.cp) { d[e.e] = d[x]+1; q.push(e.e); } } } return d[1]; } int dnc(int x,int a) { if(x==1 || a==0) return a; int ret(0); for(int& i(p[x]);i!=-1;i=ed[i].nt) { edge& e(ed[i]); int f; if(d[e.e]==d[x]+1 && (f = dnc(e.e, _min(a, e.cp))) > 0) { e.cp -= f; ed[i^1].cp += f; ret += f; a -= f; if(a==0) break; } } return ret; } int nxt[Mn]; bool isv[Mn]; void prtans(int x) { isv[x] = true; printf("%d ",x); if(nxt[x]) prtans(nxt[x]); } int main() { memset(vs,-1,sizeof vs); int n; cin >> n; int col(0),bal(0); while(true) { ++bal; adde(0,bal*2); adde(bal*2+1,1); for(int i(1),j(1);;i+=2*j+1,++j) { if(i<=bal) continue; if(i>=2*bal) break; adde(2*(i-bal),bal*2+1); } int flw(0); while(bfs()) { memcpy(p,vs,sizeof p); flw += dnc(0,INT_MAX); } if(!flw) ++col; else { for(int i(2);i<=bal*2;i+=2) for(int j(vs[i]);j!=-1;j=ed[j].nt) if(!ed[j].cp && ed[j].e>1) { nxt[i/2] = ed[j].e/2; break; } } if(col>n) break; } cout << bal-1; for(int i(1);i<bal;++i) if(!isv[i]) { cout << endl; prtans(i); } return 0; }
|