题解:P11879 [威海市赛2024] 速成之道
Solution
一个知识点可以选择有基础学、无基础学、不学。
故考虑从源点到汇点对于每一个知识点都有三条边,即将每一个知识点拆成两个点。
如果一个知识点是
假如知识点
那么对于
所以
:::success[code]
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct node{int u,v,w;};
int n,m,s,t=201,u,v,d[205],flag[205];
vector<node> edges;
vector<int> e[205];
queue<int> q;
void add(int u,int v,int w){
edges.push_back({u,v,w});
edges.push_back({v,u,0});
e[u].push_back(edges.size()-2);
e[v].push_back(edges.size()-1);
}
bool bfs(){
memset(d,0,sizeof d);
while(!q.empty()) q.pop();
d[s]=1,q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(auto to:e[u]){
int v=edges[to].v;
if(!d[v]&&edges[to].w){
d[v]=d[u]+1;
q.push(v);
if(v==t) return 1;
}
}
}
return 0;
}
int dfs(int u,int flow){
if(u==t) return flow;
int sum=0;
for(int i = flag[u];i<e[u].size();i++){
int v=edges[e[u][i]].v;
if(edges[e[u][i]].w&&d[v]==d[u]+1){
int tmp=dfs(v,min(flow,edges[e[u][i]].w));
sum+=tmp,flow-=tmp,edges[e[u][i]].w-=tmp,edges[e[u][i]^1].w+=tmp;
if(!flow) break;
}
}
if(!sum) d[u]=-1;
return sum;
}
int dinic(){
int ans=0;
while(bfs()){
memset(flag,0,sizeof flag);
ans+=dfs(s,1e18);
}
return ans;
}
signed main(){
cin>>n>>m;
for(int i = 1;i<=m;i++)
cin>>u>>v,
add(u+n,v,1e9);
for(int i = 1;i<=n;i++)
cin>>u,add(s,i,u);
for(int i = 1;i<=n;i++)
cin>>u,add(i,i+n,u);
cin>>u;
add(u+n,t,1e9);
cout<<dinic();
return 0;
}