网络流的一些基础入门题
hdu 3549
入门
#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; 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; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } int main(){ int T,n,m; cin>>T; for(int cas=1;cas<=T;cas++){ init(); cin>>n>>m; s=1; t=n; for(int i=1;i<=m;i++){ int u,v,w; scanf("%d %d %d",&u,&v,&w); add(u,v,w); } printf("Case %d: %d\n",cas,dicnic()); } return 0; }
hdu 1532
入门
#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 = 1000005; using namespace std; int cnt,s,t,n,m; 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; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } bool check(int x,int y){ if(x>n||y>m||x<1||y<1) return true; return false; } int a[205][205]; int main(){ while(~scanf("%d %d",&n,&m)){ init(); s=1; t=m; for(int i=1;i<=n;i++){ int u,v,w; cin>>u>>v>>w; add(u,v,w); } cout<<dicnic()<<"\n"; } return 0; }
hdu 3046
狼羊模型 最小割
#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; 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; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } bool check(int x,int y){ if(x>n||y>m||x<1||y<1) return true; return false; } int a[205][205]; int main(){ int cas=0; while(~scanf("%d %d",&n,&m)){ init(); s=0; t=n*m+1; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%d",&a[i][j]); if(a[i][j]==1) add(s,(i-1)*m+j,inf); if(a[i][j]==2) add((i-1)*m+j,t,inf); } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ for(int k=0;k<4;k++){ int fx=i+dir[k][0]; int fy=j+dir[k][1]; if(check(fx,fy)) continue; add((i-1)*m+j,(fx-1)*m+fy,1); } } } printf("Case %d:\n",++cas); cout<<dicnic()<<"\n"; } return 0; }
hdu 3605
n很大 m很小 我们可以状压 一个人就是一个状态 因为m最大为10 状态只有2^10次 我们直接s->状态->星球->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 = 100005; using namespace std; int cnt,s,t,n,m; 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; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } map<int,int> mp; int main(){ while(~scanf("%d %d",&n,&m)){ init(); mp.clear(); s=0; for(int i=1;i<=n;i++){ int res=0; int op; for(int j=1;j<=m;j++){ scanf("%d",&op); if(op==1) res=res+(1<<j); } mp[res]++; // cout<<res<<" "<<mp[res]<<endl; } int tot=0; int sz=mp.size(); for(auto x:mp){ ++tot; add(s,tot,x.second); for(int i=1;i<=m;i++){ if(x.first&(1<<i)){ add(tot,i+sz,x.second); } } } for(int i=1;i<=m;i++){ int flow; scanf("%d",&flow); add(i+sz,sz+m+1,flow); } t=m+sz+1; if(dicnic()==n){ puts("YES"); }else { puts("NO"); } } return 0; }
hdu 3572
以方案->时间建边 时间流向汇点 最大流满流即可
#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; 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; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } bool fg[1005]; int main(){ int T; cin>>T; for(int cas=1;cas<=T;cas++){ init(); scanf("%d %d",&n,&m); s=0; t=n+502; int ans=0; int start,end,num; for(int i=1;i<=n;i++){ scanf("%d %d %d",&num,&start,&end); add(s,i,num); ans+=num; for(int j=start;j<=end;j++){ add(i,j+n,1); } } for(int i=1;i<=500;i++){ add(i+n,t,m); } if(dicnic()==ans){ printf("Case %d: Yes\n\n",cas); }else { printf("Case %d: No\n\n",cas); } } return 0; }
hdu 2732
对于每个柱子拆点来限制流量
S->青蛙(flow1) 柱子->柱子次(flow 柱子承受能力) 柱子次->柱子(能跳到的 flow inf) 柱子次->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 = 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; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } char mp[25][25]; int main(){ int T; scanf("%d",&T); for(int cas=1;cas<=T;cas++){ scanf("%d %d",&n,&k); init(); for(int i=1;i<=n;i++) scanf("%s",mp[i]+1); m=strlen(mp[1]+1); int tot=n*m; s=0; t=2*tot+1; // cout<<n<<" "<<m<<endl; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(mp[i][j]>'0'){ add((i-1)*m+j,(i-1)*m+j+tot,mp[i][j]-'0'); if(i<=k||i+k>n||j<=k||j+k>m){ add((i-1)*m+j+tot,t,inf); }else { for(int x=-k;x<=k;x++){ for(int y=abs(x)-k;y<=k-abs(x);y++){ // cout<<x<<" "<<y<<endl; int fx=x+i; int fy=y+j; if(fx==i&&fy==j) continue; add((i-1)*m+j+tot,(fx-1)*m+fy,inf); } } } } } } int ans=0; for(int i=1;i<=n;i++){ scanf("%s",mp[i]+1); for(int j=1;j<=m;j++){ if(mp[i][j]=='L'){ ans++; add(s,(i-1)*m+j,1); } } } int sum=dicnic(); if(ans-sum==0){ printf("Case #%d: no lizard was left behind.\n",cas); }else if(ans-sum==1){ printf("Case #%d: 1 lizard was left behind.\n",cas); }else { printf("Case #%d: %d lizards were left behind.\n",cas,ans-sum ); } } return 0; }
hdu 3879
最大权闭合子图 源点连方案数 flow 为利润 车站连汇点flow为价格 答案为总利润-最小割
#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; } void init(){ memset(head,-1,sizeof(head)); cnt=0; } int main(){ int u,v,w; while(~scanf("%d %d",&n,&m)){ init(); s=0; t=n+m+1; for(int i=1;i<=n;i++){ scanf("%d",&w); add(i,t,w); } int ans=0; for(int i=1;i<=m;i++){ scanf("%d %d %d",&u,&v,&w); add(s,i+n,w); add(i+n,v,inf); add(i+n,u,inf); ans+=w; } printf("%d\n", ans-dicnic()); } return 0; }
hdu 3917
同上一题 注意下公司的选择(选全部)以公司建即可
#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; vector<pair<int,int> > v[1005]; int cnt,s,t,n,m,k; int head[maxn],Next[maxn*20],to[maxn*20]; int flow[maxn*20],dep[maxn],cur[maxn]; struct node{ int u,v,id,val; }p[3005]; 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 cost[5005]; void init(int n){ memset(head,-1,sizeof(head)); for(int i=1;i<=n;i++) v[i].clear(); memset(cost,0,sizeof(cost)); cnt=0; } int main(){ while(scanf("%d %d",&n,&m)){ if(n==0&&m==0) break; init(n); s=0; t=m+1; int sum=0; for(int i=1;i<=m;i++){ int x; scanf("%d",&x); add(s,i,x); sum+=x; } scanf("%d",&k); for(int i=1;i<=k;i++){ scanf("%d %d %d %d",&p[i].u,&p[i].v,&p[i].id,&p[i].val); cost[p[i].id]+=p[i].val; v[p[i].u].push_back({p[i].v,p[i].id}); } for(int i=1;i<=k;i++){ int uu=p[i].id; int vv=p[i].v; for(auto x:v[vv]){ if(x.second==uu) continue; add(uu,x.second,inf); // cout<<uu<<" -> "<<x.second<<" cost: "<<inf<<endl; } } for(int i=1;i<=m;i++){ add(i,t,cost[i]); // cout<<i<<" -> "<<t<<" cost: "<<cost[i]<<endl; } int flow=sum-dicnic(); printf("%d\n", flow>0?flow:0); } return 0; }