P3872 [TJOI2010] 电影迷题解
一眼网络流,考虑建图。
根据贪心思想,我们最好选完所有正权点,不选所有负权点。
Trick:考虑
但他还有一些限制,就是选了这个不选那个就会减少体验值,不妨设
Trick:当题目这样有减少体验值,可以考虑最小割
考虑割掉
最后用所有正权点的和减去最大流就好了
上代码:
#include<bits/stdc++.h> #define ll long long using namespace std; const ll N=110000,INF=1e12; ll n,m,a[N],s,t; ll h[N],e[N],ne[N],w[N],idx=1; void add(ll a,ll b,ll c) { e[++idx]=b; w[idx]=c; ne[idx]=h[a]; h[a]=idx; e[++idx]=a; w[idx]=0; ne[idx]=h[b]; h[b]=idx; } ll dep[N],now[N],ans,ans1; bool bfs() { for(ll i=s;i<=t;i++) dep[i]=INF; dep[s]=1; queue<ll> q; q.push(s); now[s]=h[s]; while(!q.empty()) { ll wz=q.front(); q.pop(); for(ll i=h[wz];i;i=ne[i]) { ll j=e[i]; if(w[i]==0) continue;//只枚举大于0的边 if(dep[j]==INF) { now[j]=h[j]; dep[j]=dep[wz]+1; q.push(j); if(j==t) return true; } } } return false; } ll dfs(ll wz,ll k) { if(wz==t) return k; ll sum,res=0; for(ll i=now[wz];i&&k;i=ne[i]) { now[wz]=i; ll j=e[i]; if(w[i]==0||dep[j]!=dep[wz]+1) continue; sum=dfs(j,min(k,w[i])); if(sum==0) dep[j]=INF; res+=sum; k-=sum; w[i]-=sum; w[i^1]+=sum; } return res; } int main() { scanf("%lld %lld",&n,&m); s=0,t=n+1; for(ll i=1;i<=n;i++) { scanf("%lld",&a[i]); if(a[i]>0) add(s,i,a[i]),ans1+=a[i]; if(a[i]<0) add(i,t,-a[i]); } ll t1,t2,t3; for(ll i=1;i<=m;i++) { scanf("%lld %lld %lld",&t1,&t2,&t3); add(t1,t2,t3); } while(bfs()) ans+=dfs(s,INF); printf("%lld\n",ans1-ans); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!