hdu 6582/bzoj 1266
最短路建图 两次dijstra求出最短路 然后把最短路的边建网络流
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 100005; using namespace std; int cnt,s,t,n,m,k; int head[maxn],Next[maxn*20],to[maxn*20]; int flow[maxn*20],dep[maxn],cur[maxn]; inline void add(int u,int v,int w){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt++]=w; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt++]=0; } int dfs(int u,int cost){ if(u==t) return cost; for(int &i=cur[u];i!=-1;i=Next[i]){ if(dep[to[i]]==dep[u]+1&&flow[i]>0){ int dis=dfs(to[i],min(flow[i],cost)); if(dis>0){ flow[i]-=dis; flow[i^1]+=dis; return dis; } } } return 0; } int bfs(){ queue<int> q; q.push(s); memset(dep,0,sizeof(dep)); dep[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=Next[i]){ if(flow[i]>0&&dep[to[i]]==0){ dep[to[i]]=dep[u]+1; q.push(to[i]); } } } if(dep[t]>0) return 1; return 0; } int dicnic(){ int ans=0; while(bfs()){ int cost; for(int i=0;i<=t+2;i++){ cur[i]=head[i]; } while(cost=dfs(s,inf)) ans+=cost; } return ans; } int dis[505],vis[505],dis2[505]; void init(){ memset(head,-1,sizeof(head)); memset(dis,inf,sizeof(dis)); memset(dis2,inf,sizeof(dis2)); cnt=0; } struct node{ int u,v,dis,val; }p[124755]; vector<pair<int,pair<int,int> > > G[505]; void dijstra(int dis[],int s){ memset(vis,0,sizeof(vis)); priority_queue< pair<int,int> , vector<pair<int,int> > ,greater<pair<int,int> > > q; q.push({0,s}); dis[s]=0; while(!q.empty()){ int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; int len=G[u].size(); for(int i=0;i<len;i++){ int v=G[u][i].first; int d=G[u][i].second.first; if(dis[v]>dis[u]+d){ dis[v]=dis[u]+d; q.push({dis[v],v}); } } } } int main(){ int n,m; init(); scanf("%d %d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d %d %d %d",&p[i].u,&p[i].v,&p[i].dis,&p[i].val); G[p[i].u].push_back({p[i].v,{p[i].dis,p[i].val}}); G[p[i].v].push_back({p[i].u,{p[i].dis,p[i].val}}); } dijstra(dis,1); dijstra(dis2,n); for(int i=1;i<=n;i++){ int len=G[i].size(); for(int j=0;j<len;j++){ pair<int,pair<int,int> > x=G[i][j]; if(dis[i]+dis2[x.first]+x.second.first==dis[n]){ add(i,x.first,x.second.second); } } } s=1; t=n; printf("%d %d ",dis[n],dicnic()); return 0; }
bzoj 1305
二分+最大流 每次check下 是否能满流
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 100005; using namespace std; int cnt,s,t,n,m,k; int head[maxn],Next[maxn*20],to[maxn*20]; int flow[maxn*20],dep[maxn],cur[maxn]; inline void add(int u,int v,int w){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt++]=w; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt++]=0; } int dfs(int u,int cost){ if(u==t) return cost; for(int &i=cur[u];i!=-1;i=Next[i]){ if(dep[to[i]]==dep[u]+1&&flow[i]>0){ int dis=dfs(to[i],min(flow[i],cost)); if(dis>0){ flow[i]-=dis; flow[i^1]+=dis; return dis; } } } return 0; } int bfs(){ queue<int> q; q.push(s); memset(dep,0,sizeof(dep)); dep[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=Next[i]){ if(flow[i]>0&&dep[to[i]]==0){ dep[to[i]]=dep[u]+1; q.push(to[i]); } } } if(dep[t]>0) return 1; return 0; } int dicnic(){ int ans=0; while(bfs()){ int cost; for(int i=0;i<=t+2;i++){ cur[i]=head[i]; } while(cost=dfs(s,inf)) ans+=cost; } return ans; } char mp[55][55]; void init(){ memset(head,-1,sizeof(head)); cnt=0; } bool check(int f){ init(); for(int i=1;i<=n;i++){ add(s,i,f); add(i,i+n,k); add(i+2*n,i+3*n,k); add(i+3*n,t,f); } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(mp[i][j]=='Y'){ add(i,j+3*n,1); }else { add(i+n,j+2*n,1); } } } int res=dicnic(); if(res==n*f) return true; return false; } int main(){ scanf("%d %d",&n,&k); for(int i=1;i<=n;i++) scanf("%s",mp[i]+1); int l=0; int r=n; int ans=0; s=0; t=4*n+1; while(l<=r){ int m=(l+r)>>1; if(check(m)){ ans=m; l=m+1; }else { r=m-1; } } cout<<ans<<" "; return 0; }
bzoj 3438
最大权闭合子图
对于每种作物只能种在A或者B 所以 S->i i->T 表示割掉一个
对于组合同理
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 200005; using namespace std; int cnt,s,t,n,m,k; int head[3005],Next[maxn*20],to[maxn*20]; int flow[maxn*20],dep[3005],cur[3005]; void add(int u,int v,int w){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt++]=w; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt++]=0; } int dfs(int u,int cost){ if(u==t) return cost; for(int &i=cur[u];i!=-1;i=Next[i]){ if(dep[to[i]]==dep[u]+1&&flow[i]>0){ int dis=dfs(to[i],min(flow[i],cost)); if(dis>0){ flow[i]-=dis; flow[i^1]+=dis; return dis; } } } return 0; } int bfs(){ queue<int> q; q.push(s); memset(dep,0,sizeof(dep)); dep[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=Next[i]){ if(flow[i]>0&&dep[to[i]]==0){ dep[to[i]]=dep[u]+1; if(to[i]==t) return 1; q.push(to[i]); } } } if(dep[t]>0) return 1; return 0; } int dicnic(){ int ans=0; while(bfs()){ int cost; for(int i=0;i<=t+2;i++){ cur[i]=head[i]; } while(cost=dfs(s,inf)) ans+=cost; } return ans; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } int main(){ init(); int x; scanf("%d",&n); int sum=0; s=0; t=3002; for(int i=1;i<=n;i++){ scanf("%d",&x); sum+=x; add(s,i,x); } for(int i=1;i<=n;i++){ scanf("%d",&x); sum+=x; add(i,t,x); } scanf("%d",&m); int tot=n+1; int a,b; while(m--){ scanf("%d",&k); scanf("%d %d",&a,&b); sum+=a+b; add(s,++tot,a); add(++tot,t,b); while(k--){ scanf("%d",&x); add(tot-1,x,inf); add(x,tot,inf); } } // cout<<sum<<" "<<dicnic()<<endl; cout<<sum-dicnic()<<endl; return 0; }
bzoj 3894
同上题
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 100005; using namespace std; int cnt,s,t,n,m,k; int head[maxn],Next[maxn*20],to[maxn*20]; int flow[maxn*20],dep[maxn],cur[maxn]; int dir[5][2]={0,0,1,0,-1,0,0,1,0,-1}; inline void add(int u,int v,int w){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt++]=w; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt++]=0; } int dfs(int u,int cost){ if(u==t) return cost; for(int &i=cur[u];i!=-1;i=Next[i]){ if(dep[to[i]]==dep[u]+1&&flow[i]>0){ int dis=dfs(to[i],min(flow[i],cost)); if(dis>0){ flow[i]-=dis; flow[i^1]+=dis; return dis; } } } return 0; } int bfs(){ queue<int> q; q.push(s); memset(dep,0,sizeof(dep)); dep[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=Next[i]){ if(flow[i]>0&&dep[to[i]]==0){ dep[to[i]]=dep[u]+1; q.push(to[i]); } } } if(dep[t]>0) return 1; return 0; } int dicnic(){ int ans=0; while(bfs()){ int cost; for(int i=0;i<=t+2;i++){ cur[i]=head[i]; } while(cost=dfs(s,inf)) ans+=cost; } return ans; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } int id(int i,int j){ return (i-1)*m+j; } bool check(int x,int y){ if(x>n||x<1||y>m||y<1) return true; return false; } int main(){ int sum=0; init(); scanf("%d %d",&n,&m); s=0; t=3*n*m+1; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&k); sum+=k; add(s,id(i,j),k); } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&k); sum+=k; add(id(i,j),t,k); } } int tot=n*m+1; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&k); sum+=k; add(s,tot,k); for(int p=0;p<=4;p++){ int fx=i+dir[p][0]; int fy=j+dir[p][1]; if(check(fx,fy)) continue; add(tot,id(fx,fy),inf); } tot++; } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&k); sum+=k; add(tot,t,k); for(int p=0;p<=4;p++){ int fx=i+dir[p][0]; int fy=j+dir[p][1]; if(check(fx,fy)) continue; add(id(fx,fy),tot,inf); } tot++; } } printf("%d ",sum-dicnic()); return 0; }
hdu 3081
二分流量 用并查集来判断女生之间的关系 是否已经建图啦
每次check最大流是否为满流
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 100005; using namespace std; int cnt,s,t,n,m,k; int head[maxn],Next[maxn*20],to[maxn*20]; int flow[maxn*20],dep[maxn],cur[maxn]; int dir[4][2]={1,0,-1,0,0,-1,0,1}; inline void add(int u,int v,int w){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt++]=w; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt++]=0; } int dfs(int u,int cost){ if(u==t) return cost; for(int &i=cur[u];i!=-1;i=Next[i]){ if(dep[to[i]]==dep[u]+1&&flow[i]>0){ int dis=dfs(to[i],min(flow[i],cost)); if(dis>0){ flow[i]-=dis; flow[i^1]+=dis; return dis; } } } return 0; } int bfs(){ queue<int> q; q.push(s); memset(dep,0,sizeof(dep)); dep[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=Next[i]){ if(flow[i]>0&&dep[to[i]]==0){ dep[to[i]]=dep[u]+1; q.push(to[i]); } } } if(dep[t]>0) return 1; return 0; } int dicnic(){ int ans=0; while(bfs()){ int cost; for(int i=0;i<=t+2;i++){ cur[i]=head[i]; } while(cost=dfs(s,inf)) ans+=cost; } return ans; } int pre[205]; int vis[205][205],vis2[205][205]; int _find(int x){ return x==pre[x]?x:pre[x]=_find(pre[x]); } void init(){ memset(head,-1,sizeof(head)); cnt=0; } void build(int f){ init(); for(int i=1;i<=n;i++){ for(int j=n+1;j<=2*n;j++){ vis[i][j]=vis2[i][j]; } } s=0; t=2*n+1; for(int i=1;i<=n;i++){ for(int j=n+1;j<=2*n;j++){ if(vis[i][j]) add(i,j,1); } } for(int i=1;i<=n;i++){ add(s,i,f); add(i+n,t,f); } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(_find(i)==_find(j)){ for(int k=n+1;k<=2*n;k++){ if(vis[i][k]&&!vis[j][k]){ add(j,k,1); vis[j][k]=1; } } } } } } int main(){ int T; scanf("%d",&T); while(T--){ int u,v; scanf("%d %d %d",&n,&m,&k); memset(vis2,0,sizeof(vis2)); for(int i=1;i<=n;i++) pre[i]=i; for(int i=1;i<=m;i++){ scanf("%d %d",&u,&v); v+=n; vis[u][v]=vis2[u][v]=1; } for(int i=1;i<=k;i++){ scanf("%d %d",&u,&v); int x=_find(u); int y=_find(v); pre[x]=y; } int l=0; int r=n; int ans=0; while(l<=r){ int mid=(l+r)>>1; build(mid); if(dicnic()==n*mid){ ans=mid; l=mid+1; }else r=mid-1; } cout<<ans<<endl; } return 0; }
hdu 6118
最小费用最大流/可行流
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 100005; using namespace std; int head[maxn],Next[maxn*200],to[maxn*200]; int flow[maxn*200],dis[maxn],pre[maxn],vis[maxn],id[maxn],ct[maxn]; int cnt,s,t,n,m; inline void add(int u,int v,int w,int cost){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt]=w; ct[cnt++]=cost; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt]=0; ct[cnt++]=-cost; } bool spfa(){ memset(vis,0,sizeof(vis)); memset(dis,inf,sizeof(dis)); memset(pre,-1,sizeof(pre)); dis[s]=0; queue<int> q; q.push(s); while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=Next[i]){ int v=to[i]; int d=ct[i]; if(dis[v]>dis[u]+d&&flow[i]>0){ dis[v]=dis[u]+d; pre[v]=u; id[v]=i; if(!vis[v]){ vis[v]=1; q.push(v); } } } } // cout<<dis[t]<=0<<endl; 可行流 不加建图那句 写这个就好了 return dis[t]<inf; } int Maxflow(){ int ans=0; while(spfa()){ int Min=inf; for(int i=t;i!=s;i=pre[i]){ // cout<<i<<" "<<pre[i]<<endl; Min=min(flow[id[i]],Min); } for(int i=t;i!=s;i=pre[i]){ flow[id[i]]-=Min; flow[id[i]^1]+=Min; } ans+=dis[t]*Min; } return ans; } void init(){ memset(head,-1,sizeof(head)); cnt=0; s=0; t=n+1; } int main() { int a,b,c,d,u,v,w,i; while(~scanf("%d%d",&n,&m)){ int ans=0; init(); for(i=1;i<=n;i++){ scanf("%d%d%d%d",&a,&b,&c,&d); add(s,i,b,a); add(i,t,d,-c); add(i,t,b,-a); //允许不买了! 这样就可以求最大流啦 } for(i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); add(u,v,inf,w); add(v,u,inf,w); } printf("%d ",-Maxflow()); } return 0; }
poj 3680
同2018焦作网络赛 网络流24题的最长k区间可重
我们对于区间离散化一下
其实我们可以把区间看成一条线 其实流量为k 相邻点流量为inf
每次遇到一个区间都是从左端点流走一条流量为1的流 然后再右端点流回来
为啥可以这样 因为起始流量为k 如果再一段区间流出去k条 还没回来那么就没办法再流啦 及 最多k区间可重复
//#include<bits/stdc++.h> #include<cstring> #include<cstdio> #include<iostream> #include<queue> #include<map> #include<algorithm> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 1005; using namespace std; int cnt,s,t,n,m,k; int head[maxn],Next[maxn*200],to[maxn*200]; int flow[maxn*200],dis[maxn],ct[maxn*200]; int pre[maxn],vis[maxn],id[maxn]; void add(int u,int v,int w,int cost){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt]=w; ct[cnt++]=cost; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt]=0; ct[cnt++]=-cost; } inline int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } bool spfa(){ memset(vis,0,sizeof(vis)); memset(dis,inf,sizeof(dis)); memset(pre,-1,sizeof(pre)); dis[s]=0; queue<int> q; q.push(s); while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=Next[i]){ int v=to[i]; int d=ct[i]; if(dis[v]>dis[u]+d&&flow[i]>0){ dis[v]=dis[u]+d; pre[v]=u; id[v]=i; if(!vis[v]){ vis[v]=1; q.push(v); } } } } return dis[t]<inf; } int Maxflow(){ int ans=0; while(spfa()){ int Min=inf; for(int i=t;i!=s;i=pre[i]){ Min=min(flow[id[i]],Min); } for(int i=t;i!=s;i=pre[i]){ flow[id[i]]-=Min; flow[id[i]^1]+=Min; } ans+=dis[t]*Min; } return ans; } int q[1005],l[505],r[505],w[505]; int _; void init(){ memset(head,-1,sizeof(head)); cnt=0; _=0; } map<int,int> mp; int main(){ int T; T=read(); while(T--){ n=read(); k=read(); init(); for(int i=1;i<=n;i++){ l[i]=read();r[i]=read();w[i]=read(); q[++_]=l[i]; q[++_]=r[i]; } sort(q+1,q+1+_); int tot=0; for(int i=1;i<=_;i++){ if(i==1||q[i]!=q[i-1]) mp[q[i]]=++tot; } for(int i=1;i<tot;i++){ add(i,i+1,inf,0); } for(int i=1;i<=n;i++){ add(mp[l[i]],mp[r[i]],1,-w[i]); } s=tot+1; t=tot+2; add(s,1,k,0); add(tot,t,k,0); printf("%d ", -Maxflow()); } return 0; }
hdu 6437
最小费用最大流
我们先处理能一个接一个看的影片有哪些 同时处理他们的类型
建立一个次源点 S->S1 容量为k 费用为0 然后通过拆点来限制影片的流量 费用为 -p[i].val
最后求出来对最小费用取反就好了
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 100005; using namespace std; int head[maxn],Next[maxn*200],to[maxn*200]; int flow[maxn*200],dis[maxn],pre[maxn],vis[maxn],id[maxn],ct[maxn]; int cnt,s,t,n,m,k; inline void add(int u,int v,int w,int cost){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt]=w; ct[cnt++]=cost; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt]=0; ct[cnt++]=-cost; } bool spfa(){ memset(vis,0,sizeof(vis)); memset(dis,inf,sizeof(dis)); memset(pre,-1,sizeof(pre)); dis[s]=0; queue<int> q; q.push(s); while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=Next[i]){ int v=to[i]; int d=ct[i]; if(dis[v]>dis[u]+d&&flow[i]>0){ dis[v]=dis[u]+d; pre[v]=u; id[v]=i; if(!vis[v]){ vis[v]=1; q.push(v); } } } } return dis[t]<inf; } int Maxflow(){ int ans=0; while(spfa()){ int Min=inf; for(int i=t;i!=s;i=pre[i]){ Min=min(flow[id[i]],Min); } for(int i=t;i!=s;i=pre[i]){ flow[id[i]]-=Min; flow[id[i]^1]+=Min; } ans+=dis[t]*Min; } return ans; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } struct node{ int l,r,op,val; }p[205]; int main(){ int T,w; scanf("%d",&T); while(T--){ init(); scanf("%d %d %d %d",&n,&m,&k,&w); s=0; int ss=m+m+1; t=m+m+2; for(int i=1;i<=m;i++){ scanf("%d %d %d %d",&p[i].l,&p[i].r,&p[i].val,&p[i].op); } for(int i=1;i<=m;i++){ for(int j=1;j<=m;j++){ if(i==j) continue; if(p[j].l>=p[i].r){ add(i+m,j,1,p[i].op==p[j].op?w:0); } } } add(s,ss,k,0); for(int i=1;i<=m;i++){ add(ss,i,1,0); add(i+m,t,1,0); add(i,i+m,1,-p[i].val); } printf("%d ",-Maxflow()); } return 0; }
hdu 4888
思路:行与源点连 列与汇点连 行与列连 flow为k(最多可转移k)然后判断是否满流 满流及有解 然后判环就好啦
代码:无(哈哈哈哈)
cf 1082G
最大权闭合子图 (裸)
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 200005; using namespace std; int cnt,s,t,n,m; int head[maxn],Next[maxn*20],to[maxn*20],cur[maxn]; ll flow[maxn*20],dep[maxn]; inline void add(int u,int v,ll w){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt++]=w; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt++]=0; } ll dfs(int u,ll cost){ if(u==t) return cost; for(int &i=cur[u];i!=-1;i=Next[i]){ if(dep[to[i]]==dep[u]+1&&flow[i]>0){ ll dis=dfs(to[i],min(flow[i],cost)); if(dis>0){ flow[i]-=dis; flow[i^1]+=dis; return dis; } } } return 0; } int bfs(){ queue<int> q; q.push(s); memset(dep,0,sizeof(dep)); dep[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=Next[i]){ if(flow[i]>0&&dep[to[i]]==0){ dep[to[i]]=dep[u]+1; q.push(to[i]); } } } if(dep[t]>0) return 1; return 0; } ll dicnic(){ ll ans=0; while(bfs()){ ll cost; for(int i=0;i<=t+2;i++){ cur[i]=head[i]; } while(cost=dfs(s,INF)) ans+=cost; } return ans; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } int main(){ scanf("%d %d",&n,&m); init(); s=0; t=n+m+1; for(int i=1;i<=n;i++){ int x; scanf("%d",&x); add(i,t,x); } ll ans=0; for(int i=1;i<=m;i++){ int u,v,w; scanf("%d %d %d",&u,&v,&w); add(i+n,u,INF); add(i+n,v,INF); add(s,i+n,w); ans+=w; } printf("%I64d ",ans-dicnic()); return 0; }
GYM 101908G
https://www.cnblogs.com/MengX/p/11381343.html
2018沈阳网络赛F
有汇源上下界网络流板子
#include<bits/stdc++.h> #define FIN freopen("input.txt","r",stdin) #define ll long long #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f const int maxn = 100005; using namespace std; int cnt,s,t,n,m,k; int head[maxn],Next[maxn*20],to[maxn*20]; int flow[maxn*20],dep[maxn],cur[maxn],mp[405][405]; int dir[8][2]={1,2,1,-2,-1,2,-1,-2,-2,-1,-2,1,2,1,2,-1}; inline void add(int u,int v,int w){ Next[cnt]=head[u]; head[u]=cnt; to[cnt]=v; flow[cnt++]=w; Next[cnt]=head[v]; head[v]=cnt; to[cnt]=u; flow[cnt++]=0; } int dfs(int u,int cost){ if(u==t) return cost; for(int &i=cur[u];i!=-1;i=Next[i]){ if(dep[to[i]]==dep[u]+1&&flow[i]>0){ int dis=dfs(to[i],min(flow[i],cost)); if(dis>0){ flow[i]-=dis; flow[i^1]+=dis; return dis; } } } return 0; } int bfs(){ queue<int> q; q.push(s); memset(dep,0,sizeof(dep)); dep[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=Next[i]){ if(flow[i]>0&&dep[to[i]]==0){ dep[to[i]]=dep[u]+1; q.push(to[i]); } } } if(dep[t]>0) return 1; return 0; } int dicnic(){ int ans=0; while(bfs()){ int cost; for(int i=0;i<=t+2;i++){ cur[i]=head[i]; } while(cost=dfs(s,inf)) ans+=cost; } return ans; } int p[200005]; void init(){ memset(head,-1,sizeof(head)); memset(p,0,sizeof(p)); cnt=0; } int main(){ int cas=0; while(~scanf("%d %d %d",&n,&m,&k)){ init(); int l,r; int ss=0; int tt=n+m+1; s=n+m+2; t=n+m+3; int sum=0; scanf("%d %d",&l,&r); for(int i=1;i<=k;i++){ int u,v; scanf("%d %d",&u,&v); add(u,v+n,1); } for(int i=1;i<=n;i++){ add(ss,i,r-l); p[i]+=l; } for(int i=1;i<=m;i++){ add(i+n,tt,r-l); p[i+n]-=l; } for(int i=1;i<=n+m;i++){ if(p[i]<0) add(i,t,-p[i]); else add(s,i,p[i]),sum+=p[i]; // printf("%d ---> %d ", i,p[i]); } add(tt,ss,inf); printf("Case %d: ",++cas); if(sum==dicnic()) puts("Yes"); else puts("No"); } }