网络流24题 魔术球问题
生活随笔
收集整理的這篇文章主要介紹了
网络流24题 魔术球问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
又是一個神奇的建圖題,建圖\(Van\)♂全不會啊
大體就是我們一個一個的把球放進來,每放進來一個,我們就求出當前的最小路徑覆蓋數(當前頂點數-最大流),直到最小路徑覆蓋數\({>}\)柱子數。此時的球的編號\(-1\)就是第一問的答案。第二問就是求每一條路徑,順著推下來就好了
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<cmath> using namespace std; struct zzz{int t,len,nex; }e[100010<<1]; int head[20010],tot=1; void add(int x,int y,int z){e[++tot].t=y;e[tot].len=z;e[tot].nex=head[x];head[x]=tot; } int s=0,t=20000,vis[20010],pre[20010]; bool bfs(){memset(vis,0,sizeof(vis));queue <int> q; q.push(s); vis[s]=1;while(!q.empty()){int k=q.front(); q.pop();for(int i=head[k];i;i=e[i].nex){int to=e[i].t;if(vis[to]||!e[i].len) continue;q.push(to); vis[to]=vis[k]+1;if(to==t) return 1;}}return vis[t]; } int dfs(int now,int flow){if(now==t||!flow) return flow;int rest=0,fl;for(int i=head[now];i;i=e[i].nex){int to=e[i].t;if(vis[to]==vis[now]+1&&(fl=dfs(to,min(flow,e[i].len)))){e[i].len-=fl, e[i^1].len+=fl, rest+=fl;if(rest==flow) return rest;}}if(rest<flow) vis[now]=0;return rest; } int dinic(){int ans=0;while(bfs()) ans+=dfs(s,2147483647);return ans; } int read(){int k=0; char c=getchar();for(;c<'0'||c>'9';) c=getchar();for(;c>='0'&&c<='9';c=getchar())k=(k<<3)+(k<<1)+c-48;return k; } bool jl[20010]; int next[20010]; int main(){int n=read(),cnt=0,num=0;while(cnt<=n){num++; cnt++;for(int i=1;i<num;i++)if(sqrt(i+num)==(int)sqrt(i+num))add(i,num+10000,1),add(num+10000,i,0);add(s,num,1); add(num,s,0);add(num+10000,t,1); add(t,num+10000,0);cnt-=dinic();}printf("%d\n",--num);for(int i=1;i<=num;i++){for(int j=head[i];j;j=e[j].nex){if(!e[j].len){next[i]=e[j].t-10000;break;}}}for(int i=1;i<=num;i++){if(jl[i]) continue;int x=i;while(x!=-10000){jl[x]=1; printf("%d ",x);x=next[x];}printf("\n");}return 0; }轉載于:https://www.cnblogs.com/wxl-Ezio/p/9445771.html
總結
以上是生活随笔為你收集整理的网络流24题 魔术球问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WPF 4 单词拼写检查(SpellCh
- 下一篇: 约数个数定理约数和定理