「网络流 24 题」太空飞行计划
大意: 个实验, 每个实验只能进行一次, 第实验需要的仪器集合, 收益. 种仪器, 第种仪器花费, 每种仪器可以多次使用. 求最大收益.
数据范围
最大权闭合子图.
源点向第个实验连边权为, 第个实验向集合中的仪器连边权, 仪器向汇点连边权. 则减去的最小割就为最大收益.
对于实验与间的割的含义为不选这个实验, 对于仪器与之间的割的含义为选这个仪器.
跑完最大流后仍与连通的点即为最优方案.
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 114 115 116 117 118 | #include <iostream> #include <sstream> #include <algorithm> #include <cstdio> #include <math.h> #include <set> #include <map> #include <queue> #include <string> #include <string.h> #include <bitset> #include <unordered_map> #define REP(i,a,n) for(int i=a;i<=n;++i) #define PER(i,a,n) for(int i=n;i>=a;--i) #define hr putchar(10) #define pb push_back #define lc (o<<1) #define rc (lc|1) #define mid ((l+r)>>1) #define ls lc,l,mid #define rs rc,mid+1,r #define x first #define y second #define io std::ios::sync_with_stdio(false) #define endl '\n' #define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;}) using namespace std; typedef long long ll; typedef pair< int , int > pii; const int P = 1e9+7, P2 = 998244353, INF = 0x3f3f3f3f; ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;} ll qpow(ll a,ll n) {ll r=1%P; for (a%=P;n;a=a*a%P,n>>=1) if (n&1)r=r*a%P; return r;} ll inv(ll x){ return x<=1?1:inv(P%x)*(P-P/x)%P;} inline int rd() { int x=0; char p= getchar (); while (p< '0' ||p> '9' )p= getchar (); while (p>= '0' &&p<= '9' )x=x*10+p- '0' ,p= getchar (); return x;} //head #ifdef ONLINE_JUDGE const int N = 1e6+10; #else const int N = 999; #endif int n, m, S, T; struct edge { int v,w,next; } e[N]; int head[N], dep[N], vis[N], cur[N], cnt=1; queue< int > Q; void add( int u, int v, int w) { e[++cnt] = {v,w,head[u]}; head[u] = cnt; e[++cnt] = {u,0,head[v]}; head[v] = cnt; } int bfs() { REP(i,1,T) dep[i]=INF,vis[i]=0,cur[i]=head[i]; dep[S]=0,Q.push(S); while (Q.size()) { int u = Q.front(); Q.pop(); for ( int i=head[u]; i; i=e[i].next) { if (dep[e[i].v]>dep[u]+1&&e[i].w) { dep[e[i].v]=dep[u]+1; Q.push(e[i].v); } } } return dep[T]!=INF; } int dfs( int x, int w) { if (x==T) return w; int used = 0; for ( int i=cur[x]; i; i=e[i].next) { cur[x] = i; if (dep[e[i].v]==dep[x]+1&&e[i].w) { int flow = dfs(e[i].v,min(w-used,e[i].w)); if (flow) { used += flow; e[i].w -= flow; e[i^1].w += flow; if (used==w) break ; } } } return used; } int dinic() { int ans = 0; while (bfs()) ans+=dfs(S,INF); return ans; } int main() { cin>>m>>n; cin.ignore(); S = n+m+1, T = S+1; int sum = 0; REP(i,1,m) { string s; getline(cin,s); stringstream ss(s); int k, p; ss>>p; add(S,i,p); sum += p; while (ss>>k) add(i,k+m,INF); } REP(i,1,n) { int r; cin>>r; add(i+m,T,r); } int x = dinic(); REP(i,1,m) if (dep[i]!=INF) printf ( "%d " ,i);hr; REP(i,m+1,n+m) if (dep[i]!=INF) printf ( "%d " ,i-m);hr; printf ( "%d\n" , sum-x); } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· 赶AI大潮:在VSCode中使用DeepSeek及近百种模型的极简方法
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地