洛谷P2763 试题库问题 最大流
Code:
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 110 111 112 113 | #include<cstdio> #include<algorithm> #include<vector> #include<queue> #include<cstring> using namespace std; const int maxn=3000; const int INF=10000000; # define pb push_back int s,t; struct Edge{ int from,to,cap; Edge( int u, int v, int c):from(u),to(v),cap(c) {} }; vector<Edge>edges; vector< int >G[maxn]; struct Dicnic{ int d[maxn],vis[maxn],cur[maxn]; queue< int >Q; void addedge( int u, int v, int c){ edges.pb(Edge(u,v,c)); //正向弧 edges.pb(Edge(v,u,0)); //反向弧 int m=edges.size(); G[u].pb(m-2); G[v].pb(m-1); } int BFS() { memset (vis,0, sizeof (vis)); d[s]=0,vis[s]=1;Q.push(s); while (!Q.empty()){ int u=Q.front();Q.pop(); int sz=G[u].size(); for ( int i=0;i<sz;++i){ Edge e=edges[G[u][i]]; if (!vis[e.to]&&e.cap>0){ d[e.to]=d[u]+1,vis[e.to]=1; Q.push(e.to); } } } return vis[t]; } int dfs( int x, int a){ if (x==t) return a; int sz=G[x].size(); int f,flow=0; for ( int i=cur[x];i<sz;++i){ Edge e=edges[G[x][i]]; cur[x]=i; if (d[e.to]==d[x]+1&&e.cap>0){ f=dfs(e.to,min(a,e.cap)); if (f) { int u=G[x][i]; a-=f; edges[u].cap-=f; edges[u^1].cap+=f; flow+=f; if (a==0) break ; } } } return flow; } int maxflow(){ int ans=0; while (BFS()){ memset (cur,0, sizeof (cur)); ans+=dfs(s,INF); } return ans; } }op; int main() { int k,n; scanf ( "%d%d" ,&k,&n); s=0,t=k+n+1; int sum=0; for ( int i=1;i<=n;++i)op.addedge(s,i,1); for ( int i=1;i<=k;++i) { int a; scanf ( "%d" ,&a); sum+=a; op.addedge(n+i,t,a); } for ( int i=1;i<=n;++i) { int b; scanf ( "%d" ,&b); while (b--) { int a; scanf ( "%d" ,&a); op.addedge(i,a+n,1); } } int F=op.maxflow(); if (F!=sum){ printf ( "No Solution!\n" ); return 0;} for ( int u=n+1;u<=n+k;++u) { printf ( "%d: " ,u-n); int sz=G[u].size(); for ( int i=0;i<sz;++i) { int e=G[u][i]; if (e%2==1) { if (edges[e].cap==1) printf ( "%d " ,edges[e].to); } } printf ( "\n" ); } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步