【多题合集】网络流24题练习(更新至魔术球问题)
来源:互联网 发布:snmp linux版本查询 编辑:程序博客网 时间:2024/06/13 22:45
飞行员配对问题(仅求方案总数)
传送门
思路:二分图后dinic走起,各边容量为1
代码:
#include<bits/stdc++.h>#define inf 0x7ffusing namespace std;int ans,n,n1,s,t,tot=1;int first[105],dis[105],up[105];bool vis[105];queue<int>q;struct edge{ int u,v,next,w;}e[500];void add(int x,int y,int z){ e[++tot].u=x; e[tot].v=y; e[tot].w=z; e[tot].next=first[x]; first[x]=tot;}bool bfs(){ memset(dis,0,sizeof(dis)); memset(up,0,sizeof(up)); dis[s]=1; q.push(s); while (!q.empty()) { int k=q.front(); q.pop(); for (int i=first[k];i;i=e[i].next) if (!dis[e[i].v]&&e[i].w) q.push(e[i].v), dis[e[i].v]=dis[k]+1; } return dis[t];}void flow(){ int minn=0x7ff; for (int i=up[t];i;i=up[e[i].u]) minn=min(minn,e[i].w); ans+=minn; for (int i=up[t];i;i=up[e[i].u]) e[i].w-=minn,e[i^1].w+=minn;}void dfs(int x,int maxn){ if (x==t) {flow();return;} for (int i=first[x];i;i=e[i].next) if (e[i].w&&dis[e[i].v]==dis[x]+1) up[e[i].v]=i,dfs(e[i].v,min(maxn,e[i].w));}main(){ scanf("%d%d",&n,&n1); int x,y; s=n+1;t=n+2; while (scanf("%d%d",&x,&y)!=EOF) add(x,y,1), add(y,x,0), vis[x]=1; for (int i=1;i<=n;i++) if (vis[i]) add(s,i,1),add(i,s,0); else add(i,t,1),add(t,i,0); while (bfs()) dfs(s,0x7ff); printf("%d",ans);}
太空飞行计划
传送门
思路:(在codevs上调了好久,最终弃疗)
cogs上是不用输出收益为0方案,所以我们直接学习了最大权闭合子图的姿势,求出最大流,并用所有点的正权值减去它就可以了
代码:
#include<bits/stdc++.h>#define inf 0x7fffffusing namespace std;int ans,n,m,tot=1,s,t;int first[205],dis[205],up[205];bool mac[102],exps[102];queue<int>q;struct edge{ int u,v,w,next;}e[40000];void add(int x,int y,int z){ e[++tot].u=x; e[tot].v=y; e[tot].w=z; e[tot].next=first[x]; first[x]=tot;}bool bfs(){ memset(dis,0,sizeof(dis)); memset(up,0,sizeof(up)); q.push(s); dis[s]=1; while (!q.empty()) { int k=q.front(); q.pop(); for (int i=first[k];i;i=e[i].next) if (e[i].w&&!dis[e[i].v]) dis[e[i].v]=dis[k]+1,q.push(e[i].v); } return dis[t];}void flow(){ int minn=inf; for (int i=up[t];i;i=up[e[i].u]) minn=min(minn,e[i].w); ans-=minn; for (int i=up[t];i;i=up[e[i].u]) e[i].w-=minn, e[i^1].w+=minn;}void dfs(int x,int maxn){ if (x==t) {flow();return;} for (int i=first[x];i;i=e[i].next) if (e[i].w&&dis[e[i].v]==dis[x]+1) up[e[i].v]=i,dfs(e[i].v,min(maxn,e[i].w));}main(){ scanf("%d%d",&m,&n); s=m+n+1;t=m+n+2; int x; for (int i=1;i<=m;i++) { scanf("%d",&x); ans+=x; add(s,i+n,x); add(i+n,s,0); while (1) { scanf("%d",&x); add(i+n,x,inf); add(x,i+n,0); if (getchar()!=' ') break; } } for (int i=1;i<=n;i++) scanf("%d",&x),add(i,t,x),add(t,i,0); while (bfs()) dfs(s,inf); for (int i=first[s];i;i=e[i].next) if (dis[e[i].v]) exps[e[i].v-n]=1; for (int i=first[t];i;i=e[i].next) if (dis[e[i].v]) mac[e[i].v]=1; for (int i=1;i<=m;i++) if (exps[i]) printf("%d ",i); puts(""); for (int i=1;i<=n;i++) if (mac[i]) printf("%d ",i); puts(""); printf("%d",ans);}
圆桌问题
传送门
思路:这个构图太简单……不说了
注意:
1.时间上的优化!我之前写的这些都是扯淡!
2.别上codevs评测,没有SPJ
代码:
#include<bits/stdc++.h>using namespace std;int n,m,s,t,tot=1,ans,sum;int first[500],dis[500],num[500][500],up[500],cur[500],cnt[500];queue<int>q;struct edge{ int u,v,next,w;}e[100000];void add(int x,int y,int z){ e[++tot].u=x; e[tot].v=y; e[tot].w=z; e[tot].next=first[x]; first[x]=tot;}bool bfs(){ memset(dis,0,sizeof(dis)); dis[s]=1; q.push(s); while (!q.empty()) { int k=q.front(); q.pop(); for (int i=first[k];i;i=e[i].next) if (!dis[e[i].v]&&e[i].w) dis[e[i].v]=dis[k]+1,q.push(e[i].v); } if (dis[t]) for (int i=1;i<=t;i++) cur[i]=first[i]; return dis[t];}void flow(){ int minn=0x7fffff; for (int i=up[t];i;i=up[e[i].u]) minn=min(minn,e[i].w); if (!minn) return; ans+=minn; for (int i=up[t];i;i=up[e[i].u]) { e[i].w-=minn;e[i^1].w+=minn; if (e[i].u<=m&&e[i].v<=n+m) num[e[i].u][e[i].v-m]^=1; else if (e[i].v<=m&&e[i].u<=n+m) num[e[i].v][e[i].u-m]^=1; }}int dfs(int x,int maxn){ if (x==t) {flow();return maxn;} int used=0; for (int i=cur[x];i;i=e[i].next) if (dis[e[i].v]==dis[x]+1) { up[e[i].v]=i; int flow=dfs(e[i].v,min(maxn,e[i].w)); used+=flow; if (e[i].w) cur[x]=i; if (used==maxn) return maxn; } return used; }main(){ scanf("%d%d",&m,&n); int x; s=n+m+1;t=n+m+2; for (int i=1;i<=m;i++) scanf("%d",cnt+i), sum+=cnt[i], add(s,i,cnt[i]), add(i,s,0); for (int i=1;i<=n;i++) scanf("%d",&x), add(i+m,t,x), add(t,i+m,0); for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) add(i,j+m,1), add(j+m,i,0); while (bfs()) dfs(s,0x7ffff); if (ans<sum) {printf("0");return 0;} puts("1"); for (int i=1;i<=m;i++) { for (int j=1;j<=n;j++) if (num[i][j]) printf("%d ",j); puts(""); }}
最长上升子序列问题
传送门
思路:发现网上大部分都是最大流拆点,而我写了个半残的费用流……
1.s->i连容量为1,费用为-1的边
2.i->t连容量为1,费用为0的边
3.i->j(a[i]<a[j])连容量为1,费用为-1的边
跑最小费用即可,算长度的话只用记录每次增广路上的费用总和就行了(不要乘流量,单算费用)
不用DP干掉1,2问
第3问把s->1,s->n,1->t,n->t的边容量无穷大就行了
注意:
求的是最长不下降子序列!不是最长上升子序列!这里坑爆了!
#include<bits/stdc++.h>using namespace std;int n,a[510],s,t,tot=1,len,ans=1;int first[510],up[510],dis[510];bool vis[510];queue<int> q;struct edge{ int u,v,w,next,cost;}e[200000];void add(int x,int y,int z,int c){ e[++tot].u=x; e[tot].v=y; e[tot].w=z; e[tot].cost=c; e[tot].next=first[x]; first[x]=tot;}bool spfa(){ memset(dis,63,sizeof(dis)); memset(up,0,sizeof(up)); dis[s]=0;vis[s]=1; q.push(s); while (!q.empty()) { int k=q.front(); q.pop(); vis[k]=0; for (int i=first[k];i;i=e[i].next) if (e[i].w&&dis[e[i].v]>dis[k]+e[i].cost) { dis[e[i].v]=dis[k]+e[i].cost; up[e[i].v]=i; if (!vis[e[i].v]) vis[e[i].v]=1,q.push(e[i].v); } } return dis[t]<0x7ffff;}int flow(){ int p=0,minn=0x7fffff; for (int i=up[t];i;i=up[e[i].u]) minn=min(e[i].w,minn), p+=e[i].cost; for (int i=up[t];i;i=up[e[i].u]) e[i].w-=minn, e[i^1].w+=minn; return p;}main(){ scanf("%d",&n); s=n+1;t=n+2; for (int i=1;i<=n;i++) { scanf("%d",a+i); add(s,i,1,-1); add(i,s,0,1); add(i,t,1,0); add(t,i,0,0); for (int j=1;j<i;j++) if (a[j]<=a[i]) add(j,i,1,-1), add(i,j,0,1); } for (int i=tot+1;i<=tot*2;i++) e[i]=e[i-tot]; while (spfa()) { if (!len) len=flow(); else if (len!=flow()) break; else ans++; } printf("%d\n%d\n",-len,ans); for (int i=1;i<=tot;i++) { e[i]=e[i+tot]; if ((e[i].u==s&&e[i].v==n)||(e[i].u==s&&e[i].v==1)) e[i].w=0x7ff; if ((e[i].u==n&&e[i].v==t)||(e[i].u==1&&e[i].v==t)) e[i].w=0x7ff; } ans=1;len=0; while (spfa()) { if (!len) len=flow(); else if (len!=flow()) break; else ans++; } printf("%d",ans);}
最小路径覆盖问题
传送门
思路:
二分图最大流,答案=点数-流量和
方案数从1-n枚举dfs找路径即可,要求流量为0
注意:输出格式注意!最后要换行!codevs上只用输出方案数!
#include<bits/stdc++.h>using namespace std;int n,m,tot=1,s,t;int first[320],dis[320],cur[320],ans;int num[320];bool vis[320];queue<int>q;struct edge{ int u,v,w,next;}e[15000];void add(int x,int y,int z){ e[++tot].u=x; e[tot].v=y; e[tot].w=z; e[tot].next=first[x]; first[x]=tot;}bool bfs(){ memset(dis,0,sizeof(dis)); dis[s]=1; q.push(s); while (!q.empty()) { int k=q.front(); q.pop(); for (int i=first[k];i;i=e[i].next) if (e[i].w&&!dis[e[i].v]) dis[e[i].v]=dis[k]+1, q.push(e[i].v); } if (dis[t]) for (int i=1;i<=t;i++) cur[i]=first[i]; return dis[t];}int dfs(int x,int maxn){ if (x==t) {return maxn;} int used=0; for (int i=cur[x];i;i=e[i].next) if (dis[e[i].v]==dis[x]+1) { int k=dfs(e[i].v,min(maxn,e[i].w)); e[i].w-=k;e[i^1].w+=k; used+=k; if (e[i].w) cur[x]=i; if (used==maxn) return maxn; } if (!used) dis[x]=0; return used;}void find(int x){ num[++num[0]]=x; vis[x]=1; for (int i=first[x];i;i=e[i].next) if (!e[i].w&&e[i].v!=s&&!vis[e[i].v-n]) find(e[i].v-n);}main(){ freopen("path3.in","r",stdin); freopen("path3.out","w",stdout); scanf("%d%d",&n,&m); int x,y; for (int i=1;i<=m;i++) scanf("%d%d",&x,&y), add(x,y+n,1), add(y+n,x,0); s=(n<<1)+1;t=n+1<<1; for (int i=1;i<=n;i++) add(s,i,1), add(i,s,0), add(i+n,t,1), add(t,i+n,0); while (bfs()) ans+=dfs(s,0x7ff); for (int i=1;i<=n;i++) if (!vis[i]) { num[0]=0,find(i); for (int i=1;i<=num[0];i++) printf("%d%c",num[i]," \n"[i==num[0]]); } printf("%d\n",n-ans);}
餐巾计划问题
传送门1
传送门2
思路:
感觉好厉害,一开始没有考虑流量守恒,建图完全错了,该连源点的连汇点,该连汇点的连了源点(s连新餐巾,t连旧餐巾)然后就一直买啊买也不洗……改一下就连买都不买了……后来看了高大哥的课件建图,感觉自己还是功力不深啊!!
代码:
#include<bits/stdc++.h>#define inf 0x7ffffusing namespace std;int n,f,c1,c2,t1,t2,s,t,tot=1,ans;bool vis[2010];int dis[2010],first[2010],up[2010];queue<int>q;struct edge{ int u,v,w,cost,next;}e[200000];void add(int x,int y,int z,int c){ e[++tot].u=x; e[tot].v=y; e[tot].w=z; e[tot].cost=c; e[tot].next=first[x]; first[x]=tot;}bool spfa(){ memset(dis,63,sizeof(dis)); memset(up,0,sizeof(up)); q.push(s); dis[s]=0;vis[s]=1; while (!q.empty()) { int k=q.front(); q.pop(); vis[k]=0; for (int i=first[k];i;i=e[i].next) if (e[i].w&&dis[e[i].v]>dis[k]+e[i].cost) { dis[e[i].v]=dis[k]+e[i].cost; up[e[i].v]=i; if (!vis[e[i].v]) vis[e[i].v]=1,q.push(e[i].v); } } return dis[t]<inf;}void flow(){ int minn=inf; for (int i=up[t];i;i=up[e[i].u]) minn=min(e[i].w,minn); for (int i=up[t];i;i=up[e[i].u]) e[i].w-=minn, e[i^1].w+=minn, ans+=minn*e[i].cost;}main(){// scanf("%d%d%d%d%d%d",&n,&f,&t1,&c1,&t2,&c2);codevs上的// scanf("%d%d%d%d%d%d",&n,&t1,&t2,&f,&c1,&c2);// t1++;t2++;BZOJ上的 s=(n<<1)+1;t=1+n<<1; int x; for (int i=1;i<=n;i++) { scanf("%d",&x); add(i+n,t,x,0); add(t,i+n,0,0); add(s,i,x,0); add(i,s,0,0); add(s,i+n,inf,f); add(i+n,s,0,-f); if (i+1<=n) add(i,i+1,inf,0),add(i+1,i,0,0); if (i+t1<=n) add(i,i+t1+n,inf,c1),add(i+t1+n,i,0,-c1); if (i+t2<=n) add(i,i+t2+n,inf,c2),add(i+t2+n,i,0,-c2); } while (spfa()) flow(); printf("%d",ans);}
星际转移问题(家园)
传送门1
传送门2
思路:数据比较小,可以枚举时间动态开点连边,把图分层,各个太空站在每一个时刻都是一个独立的点,样例中的
2 2 1
1 3 0 1 2
1 3 1 2 –1
构图为这样(没有连边的原因是画出来就很乱,所以不连了)
如果我们把时刻为t时的i点标号为st[t][i]且在这个飞船的下一站为next[i],我们要连的就是
同时,每个太空站是可以留人的,所以还要连
然后枚举时间由1->+∞跑最大流,当总流量>=t时就可以停下了
注意:
1.我们不可能一直把时间枚举下去,差不多t=500(可能更小)的时候就可以停下输出无解了
2.给点标号着实让我蛋疼了好久,大家自己感受下吧
#include<bits/stdc++.h>#define inf 0x7fffusing namespace std;int ans,times,n,m,k,tot=1,s,t;int cur[5000],dis[5000],first[5000],p[30],st[30][17],num[30];queue<int>q;struct edge{ int u,v,w,next;}e[20000];void add(int x,int y,int z){ e[++tot].u=x; e[tot].v=y; e[tot].w=z; e[tot].next=first[x]; first[x]=tot;}bool bfs(){ memset(dis,0,sizeof(dis)); q.push(s);dis[s]=1; while (!q.empty()) { int k=q.front(); q.pop(); for (int i=first[k];i;i=e[i].next) if (!dis[e[i].v]&&e[i].w) dis[e[i].v]=dis[k]+1,q.push(e[i].v); } cur[s]=first[s];cur[t]=first[t]; if (dis[t]) for (int i=1;i<=times*m;i++) cur[i]=first[i]; return dis[t];}int dfs(int x,int maxn){ if (x==t) return maxn; int used=0; for (int i=cur[x];i;i=e[i].next) if (dis[e[i].v]==dis[x]+1) { int k=dfs(e[i].v,min(maxn,e[i].w)); used+=k; e[i].w-=k; e[i^1].w+=k; if(e[i].w) cur[x]=i; if (used==maxn) return maxn; }if (!used) dis[x]=0; return used;}main(){ scanf("%d%d%d",&n,&m,&k); s=4999;t=4998; for (int i=1;i<=m;i++) { scanf("%d%d",p+i,num+i); for (int j=0;j<num[i];j++) { scanf("%d",st[i]+j); if (st[i][j]<=0) st[i][j]+=4999; } } while (++times<=500) { for (int i=1;i<=m;i++) { int x,y; if (st[i][(times-1)%num[i]]==s) x=s; else if (st[i][(times-1)%num[i]]==t) x=t; else x=st[i][(times-1)%num[i]]+n*(times-1); if (st[i][times%num[i]]==s) y=s; else if (st[i][times%num[i]]==t) y=t; else y=st[i][times%num[i]]+n*times; add(x,y,p[i]); add(y,x,0); } for (int i=n*(times-1)+1;i<=n*(times-1)+n;i++) add(i,i+n,inf),add(i+n,i,0); while (bfs()) ans+=dfs(s,0x7ff); if (ans>=k) printf("%d",times),exit(0); } printf("0");}
骑士共存问题
传送门
思路:根据所在行列之和x+y的奇偶来进行二分图,然后跑dinic
s->奇 容量为1
偶数->t 容量为1
奇数->被他影响的8个点 容量为inf
最后得出的最大流就是放完最多数后的不能放的点(不包括m个点),答案就是n*n-m-maxflow
代码:
#include<bits/stdc++.h>#define inf 0x7ffff#define pd(x,y,z) (x<=y&&y<=z)using namespace std;int ans,s,t,n,m,x,y,tot=1;int dis[80010],first[80010],cur[80010];int dx[9]={0,-1,-2,-2,-1,1,2,2,1},dy[9]={0,-2,-1,1,2,-2,-1,1,2};bool vis[80010];queue<int>q;struct edge{ int u,v,w,next;}e[410000];void add(int x,int y,int z){ e[++tot]=(edge){x,y,z,first[x]}; first[x]=tot;}bool bfs(){ memset(dis,0,sizeof(dis)); q.push(s);dis[s]=1; while (!q.empty()) { int k=q.front(); q.pop(); for (int i=first[k];i;i=e[i].next) if (e[i].w&&!dis[e[i].v]) q.push(e[i].v),dis[e[i].v]=dis[k]+1; } if (dis[t]) for (int i=1;i<=t;i++) cur[i]=first[i]; return dis[t];}int dfs(int x,int maxn){ if (x==t) return maxn; int used=0; for (int i=cur[x];i;i=e[i].next) if (dis[e[i].v]==dis[x]+1) { int k=dfs(e[i].v,min(maxn,e[i].w)); e[i].w-=k; e[i^1].w+=k; if (e[i].w) cur[x]=i; used+=k; if (used==maxn) return maxn; } if (!used) dis[x]=0; return used;}main(){ scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) scanf("%d%d",&x,&y), vis[(x-1)*n+y]=1; s=n*n+1;t=n*n+2; for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if (!vis[(i-1)*n+j]) { x=(i-1)*n+j; if ((i+j)&1) { add(s,x,1);add(x,s,0); for (int k=1;k<=8;k++) if (pd(1,i+dx[k],n)&&pd(1,j+dy[k],n)) add(x,n*(i+dx[k]-1)+j+dy[k],inf), add(n*(i+dx[k]-1)+j+dy[k],x,0); } else add(x,t,1),add(t,x,0); } while (bfs()) ans+=dfs(s,inf); printf("%d",n*n-ans-m);}
魔术球问题(简化版)
传送门
思路:枚举答案,动态加点判断,但一开始我是暴力加边,多建了一层关于“柱子”的点,只过了9个点,后来看到黄学长的blog才幡然醒悟,合并点,这里直接求最小路径覆盖就好了,每次加入一个待放的球,跑最大流,判断一下,如果它不能归到之前的路径上就让ans++,直到ans>n
注意:codevs上没有SPJ,但要输出方案数!
#include<bits/stdc++.h>using namespace std;int n,s,t,tot=1,ans=1;struct edge{ int u,v,w,next;}e[200000];int first[3500],dis[3500];bool sr[3204];queue<int>q;void add(int x,int y,int z){e[++tot]=(edge){x,y,z,first[x]};first[x]=tot;}bool bfs(){ memset(dis,0,sizeof(dis)); q.push(s);dis[s]=1; while (!q.empty()) { int k=q.front(); for (int i=first[k];i;i=e[i].next) if (e[i].w&&!dis[e[i].v]) q.push(e[i].v),dis[e[i].v]=dis[k]+1; q.pop(); } return dis[t];}int dfs(int x,int maxn){ if (x==t) return maxn; int used=0; for (int i=first[x];i;i=e[i].next) if (dis[e[i].v]==dis[x]+1) { int k=dfs(e[i].v,min(maxn,e[i].w)); e[i].w-=k;e[i^1].w+=k; used+=k; if (used==maxn) return maxn; } if (!used) dis[x]=0; return used;}main(){ freopen("balla.in","r",stdin); freopen("balla.out","w",stdout); for (int i=1;i<=56;i++) sr[i*i]=1; t=3244; scanf("%d",&n); for (int i=1;i<=1600;i++,ans++) { add(s,i,1);add(i,s,0); for (int j=1;j<i;j++) if (sr[j+i]) add(j,i+1600,1),add(i+1600,j,0); add(i+1600,t,1); add(t,i+1600,0); while (bfs()) ans-=dfs(s,0x7f); if (ans>n) {ans=i;break;} } printf("%d",ans-1);}
方格取数问题
传送门
思路:二分图染黑白,然后就是求最大权闭合子图了,可以参照上面的太空飞行计划,流量就是点的权值
不过这道题好坑啊,之前的最大流方法总会WA三个点,只能用回最暴力的dfs单线跑流了
代码:
#include<bits/stdc++.h>#define inf 0x7fffff#define pd(x,y,z) (x<=y&&y<=z)using namespace std;int n,m,s,t,tot=1,sum,ans;int dis[1000],first[1000],cur[1000],up[1000];int dx[4]={0,0,-1,1},dy[4]={-1,1,0,0};queue<int>q;struct edge{ int u,v,w,next;}e[10000];void add(int x,int y,int z) {e[++tot]=(edge){x,y,z,first[x]};first[x]=tot;}bool bfs(){ memset(dis,0,sizeof(dis)); dis[s]=1;q.push(s); while (!q.empty()) { int k=q.front(); for (int i=first[k];i;i=e[i].next) if (e[i].w&&!dis[e[i].v]) q.push(e[i].v),dis[e[i].v]=dis[k]+1; q.pop(); } if (dis[t]) for (int i=s;i<=t;i++) cur[i]=first[i]; return dis[t];}void flow(){ int minn=inf; for (int i=up[t];i;i=up[e[i].u]) minn=min(minn,e[i].w); ans+=minn; for (int i=up[t];i;i=up[e[i].u]) e[i].w-=minn,e[i^1].w+=minn;}void dfs(int x,int maxn){ if (x==t) {flow();return;} for (int i=first[x];i;i=e[i].next) if (e[i].w&&dis[e[i].v]==dis[x]+1) up[e[i].v]=i,dfs(e[i].v,min(maxn,e[i].w));}main(){ scanf("%d%d",&n,&m); int x; t=n*m+1; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { scanf("%d",&x); sum+=x; if (((i+j)&1)) { add(s,m*(i-1)+j,x); add(m*(i-1)+j,s,0); for (int k=0;k<4;k++) if(pd(1,i+dx[k],n)&&pd(1,j+dy[k],m)) add(m*(i-1)+j,m*(i-1+dx[k])+j+dy[k],inf), add(m*(i-1+dx[k])+j+dy[k],m*(i-1)+j,0); } else add(m*(i-1)+j,t,x),add(t,m*(i-1)+j,0); } while (bfs()) dfs(s,inf); printf("%d",sum-ans);}
- 【多题合集】网络流24题练习(更新至魔术球问题)
- 【网络流24题】魔术球问题
- 【网络流24题】魔术球问题
- 【网络流24题】魔术球问题
- [网络流24题]魔术球问题
- [网络流24题]魔术球问题(简化版)
- 魔术球问题(网络24题,三)
- 线性规划与网络流24题 04魔术球问题
- 网络流与线性规划24题04魔术球问题
- [网络流24题 #4]魔术球问题
- kyeremal-网络流24题T4-魔术球问题
- 魔术球问题[网络流24题之4]
- 网络流24题之魔术球问题
- 网络流24题4 魔术球问题
- cogs396 [网络流24题]魔术球问题简化版
- 网络流24题 魔术球问题(弱化?)(二分图解)
- 线性规划与网络流24题之 魔术球问题
- 网络流24题4. 魔术球问题
- 易學原論 (4288_3)
- 《初等算法》中文版
- iOS开发框架
- 三和韓長庚 著 易學原理總論 對讀 041_080
- 第六章-数据结构入门
- 【多题合集】网络流24题练习(更新至魔术球问题)
- 【bzoj 1923】[Sdoi2010]外星千足虫(高斯消元)
- 三联莎士比亚阅读摘记
- Arm9+linux fl2440 lcd驱动移植、添加MMC支持、添加U盘支持
- String HDU5672
- dto与po转换类
- 深夜课堂:JavaScript基本概念
- C语言综合练习题(01)
- 高性能网络编程1----accept建立连接