「luogu2765」魔术球问题
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=60,M=4010,oo=2e9; 4 int n,ss=4000,tt=4001,f[M]; 5 bool vis[M]; 6 struct Edge{ 7 int from,to,flow,cap; 8 Edge(int _from=0,int _to=0,int _flow=0,int _cap=0):from(_from),to(_to),flow(_flow),cap(_cap){} 9 }; 10 int edge_tot; 11 Edge edge[100500]; 12 vector<int>point[M]; 13 void add_edge(int f,int t,int c){ 14 edge[edge_tot]=Edge(f,t,0,c); 15 point[f].push_back(edge_tot++); 16 edge[edge_tot]=Edge(t,f,0,0); 17 point[t].push_back(edge_tot++); 18 return; 19 } 20 int level[M]; 21 bool bfs(){ 22 memset(level,0,sizeof(level)); 23 queue<int>q; 24 q.push(ss); 25 level[ss]=1; 26 int x; 27 while(!q.empty()){ 28 x=q.front();q.pop(); 29 for(int i=0;i<point[x].size();i++){ 30 Edge e=edge[point[x][i]]; 31 if(e.cap>e.flow&&!level[e.to]){ 32 int nxt=edge[point[x][i]].to; 33 level[nxt]=level[x]+1; 34 q.push(nxt); 35 } 36 } 37 } 38 return level[tt]; 39 } 40 int dfs(int k,int a){ 41 if(k==tt||!a) return a; 42 int temp,ans=0; 43 for(int i=0;i<point[k].size();i++){ 44 Edge& e=edge[point[k][i]]; 45 if(e.cap>e.flow&&level[e.to]==level[k]+1&&(temp=dfs(e.to,min(a,e.cap-e.flow)))){ 46 ans+=temp,a-=temp; 47 e.flow+=temp,edge[point[k][i]^1].flow-=temp; 48 } 49 if(!a) return ans; 50 } 51 return ans; 52 } 53 int dinic(){ 54 int ans=0; 55 while(bfs()) 56 ans+=dfs(ss,oo); 57 return ans; 58 } 59 int main(){ 60 scanf("%d",&n); 61 int ans,t1,t2; 62 for(ans=1;1;ans++){ 63 add_edge(ss,(ans<<1)-1,1);add_edge((ans<<1),tt,1); 64 for(int i=1;i<ans;i++){ 65 t1=i+ans,t2=sqrt(t1); 66 if(t2*t2==t1) add_edge((ans<<1)-1,(i<<1),1); 67 } 68 t1=dinic(); 69 if(ans-t1>n) break; 70 for(int i=0;i<edge_tot;i++) edge[i].flow=0; 71 } 72 ans--; 73 printf("%d\n",ans); 74 for(int i=1;i<=ans;i++) 75 for(int j=0;j<point[(i<<1)-1].size();j++) 76 if(edge[point[(i<<1)-1][j]].flow>0){f[(edge[point[(i<<1)-1][j]].to)>>1]=i;break;} 77 for(int i=1;i<=ans;i++){ 78 if(vis[i]) continue; 79 printf("%d ",i); 80 vis[i]=1,t1=f[i]; 81 while(t1){ 82 printf("%d ",t1); 83 vis[t1]=1,t1=f[t1]; 84 } 85 printf("\n"); 86 } 87 return 0; 88 }