ybtoj Au 网络流
前言中的前言
-
由于本人过菜,有些题解会咕掉,请原谅这个蒟蒻
-
由于本人过菜,不知道什么时候就
了,想给这个机房留下点什么…… -
如果想看高效进阶的题解,建议出门左拐,去云落那里看看,保证是全网最全最好的,但不要对云落的博客好奇,更不要看云落的一言 和 云落的合集:黑夜刀己,白日爱人
-
如果解决了题解里本蒟蒻的问题,将会获得任意奖励一份(不一定是物质哦),就比如这篇题解就有一个问题
正片开始!
好耶!!!(泪目)
题面
前言
网络流 T1,板子题
正文
请自便
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf=1e9+9;
const int N=1e5+5;
int n,m,s,t,head[N],cnt=1;
struct node{int to,nxt,w;}e[N];
void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].nxt=head[u];
e[cnt].w=w;
head[u]=cnt;
}
int now[N],deep[N];
int bfs(){
for(int i=1;i<=n;i++)deep[i]=inf;
deep[s]=0;
now[s]=head[s];
queue<int> q;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(e[i].w>0&&deep[v]==inf){
q.push(v);
now[v]=head[v];
deep[v]=deep[u]+1;
if(v==t)return 1;
}
}
}
return 0;
}
int dfs(int u,int sum){
if(u==t)return sum;
int k,flow=0;
for(int i=now[u];i>0&&sum>0;i=e[i].nxt){
now[u]=i;
int v=e[i].to;
if(e[i].w>0&&(deep[v]==deep[u]+1)){
k=dfs(v,min(sum,e[i].w));
if(k==0)deep[v]=inf;
e[i].w-=k;
e[i^1].w+=k;
flow+=k;
sum-=k;
}
}
return flow;
}
signed main(){
cin>>m>>n;
s=1,t=n;
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
add(u,v,w),add(v,u,0);
}
int ans=0;
while(bfs())ans+=dfs(s,inf);
cout<<ans;
return 0;
}
后记
好难好难
题面
前言
网络流 T2,应用题
正文
建立虚拟源点和汇点;
对于每一个人能开的保险柜, 如果它没有被打开过, 则从虚拟源点到当前的人连一条流量为保险柜金币数量的边, 表示这个人可以从这个保险柜中卷走所有的金币;
对于每一个人能开的保险柜, 如果它已经被打开过了, 则从上一次可以开这个保险柜的人到当前的人连一条流量为无限大的边, 表示当前的人可以无限从上一个人索取金币;
对于每个人, 向汇点连一条流量为其想要的金币的数量。
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
const int inf=1e9+9;
int m,n,s,t,cnt=1;
int c[N],last[N],head[N];
struct node{int to,nxt,w;}e[N];
void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].w=w;
e[cnt].nxt=head[u];
head[u]=cnt;
}
int now[N],deep[N];
int bfs(){
for(int i=s;i<=t;i++)deep[i]=inf;
deep[s]=0;
now[s]=head[s];
queue<int> q;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].to;
if(e[i].w>0&&deep[v]==inf){
q.push(v);
now[v]=head[v];
deep[v]=deep[u]+1;
if(v==t)return 1;
}
}
}
return 0;
}
int dfs(int u,int sum){
if(u==t)return sum;
int k,flow=0;
for(int i=now[u];~i&&sum>0;i=e[i].nxt){
now[u]=i;
int v=e[i].to;
if(e[i].w>0&&(deep[v]==deep[u]+1)){
k=dfs(v,min(sum,e[i].w));
if(k==0)deep[v]=inf;
e[i].w-=k;
e[i^1].w+=k;
flow+=k;
sum-=k;
}
}
return flow;
}
signed main(){
cin>>m>>n;
t=n+1;
for(int i=s;i<=t;i++)head[i]=-1;
for(int i=1;i<=m;i++)cin>>c[i];
for(int i=1;i<=n;i++){
int a,b,id;
cin>>a;
while(a--){
cin>>id;
if(!last[id]){
add(s,i,c[id]);
add(i,s,0);
}else{
add(last[id],i,inf);
add(i,last[id],0);
}
last[id]=i;
}
cin>>b;
add(i,t,b);
add(t,i,0);
}
int ans=0;
while(bfs()){
ans+=dfs(s,inf);
}
cout<<ans;
return 0;
}
后记
好难好难
题面
前言
网络流 T3,应用题
正文
推个式子
不想写了
代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int inf=0x3f3f3f3f3f3f3f3f;
const int N=1e5+10;
int T,n,m,a[45][45],b,w,cnt=1;
int id(int x,int y){
return (x-1)*m+y;
}
int head[N];
struct node{int to,nxt,w;}e[N];
void add(int u,int v,int w){
e[++cnt].to=v;
e[cnt].nxt=head[u];
e[cnt].w=w;
head[u]=cnt;
}
int dx[5]={0,0,1,0,-1};
int dy[5]={0,1,0,-1,0};
int V,s,t,deep[N],now[N];
int bfs(){
for(int i=s;i<=t;i++)deep[i]=inf;
deep[s]=0;
now[s]=head[s];
queue<int>q;
q.push(s);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].to;
if(e[i].w&&deep[v]==inf){
q.push(v);
now[v]=head[v];
deep[v]=deep[u]+1;
if(v==t)return 1;
}
}
}
return 0;
}
int dfs(int u,int sum){
if(u==t)return sum;
int k,flow=0;
for(int i=now[u];~i&∑i=e[i].nxt){
now[u]=i;
int v=e[i].to;
if(e[i].w&&(deep[v]==deep[u]+1)){
k=dfs(v,min(sum,e[i].w));
if(k==0)deep[v]=inf;
e[i].w-=k;
e[i^1].w+=k;
flow+=k;
sum-=k;
}
}
return flow;
}
int ans;
bool check(int x){
memset(head,-1,sizeof(head));
memset(now,0,sizeof(now));
V=0;
cnt=1;
s=0,t=id(n,m)+1;
ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
//if(x-a[i][j]<0) return 0;
if((i+j)%2==0){V+=x-a[i][j];
add(s,id(i,j),x-a[i][j]);
///cout<<s<<" "<<id(i,j)<<endl;
add(id(i,j),s,0);
for(int k=1;k<=4;k++){
int xx=i+dx[k],yy=j+dy[k];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m){
add(id(i,j),id(xx,yy),inf);
//cout<<id(i,j)<<" "<<id(xx,yy)<<endl;
add(id(xx,yy),id(i,j),0);
}
}
}else{
add(id(i,j),t,x-a[i][j]);
//cout<<id(i,j)<<" "<<t<<endl;
add(t,id(i,j),0);
}
}
}
while(bfs()){
ans+=dfs(s,inf);
}
if(ans==V)return 1;
return 0;
}
signed main(){
cin>>T;
while(T--){
cin>>n>>m;
b=0,w=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
if((i+j)%2==0)b+=a[i][j];
else w+=a[i][j];
}
}
if(n%2&&m%2){
int x=b-w;
if(check(x))cout<<(n*m/2+1)*x-b<<endl;
else cout<<-1<<endl;
continue;
}
if(b!=w){cout<<-1<<endl;continue;}
int l=1,r=inf,an=-1;
while(l<=r){
int mid=(l+r)>>1;
//cout<<mid<<endl;
if(check(mid))r=mid-1,an=mid;
else l=mid+1;
}
if(an==-1)cout<<-1<<endl;
else cout<<an*(n*m/2)-b<<endl;
}
return 0;
}
后记
调了一下午+一晚上没调出来,云落 5 分钟调出来了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】