网络流24题+简单网络流[不更新了]
干网络流!
之前刷过一点校oj的网络流,现在忘得差不多了,开始在loj刷一下网络流24题。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=210,MAXM=5010; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline ll read(){ ll This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } ll mod=998244353; struct edge { int y,next; ll v; }e[MAXM*2]; int head[MAXN],v[MAXN],d[MAXN]; int tot=1; int n,m,s,t; queue<int>q; void add(int x,int y,ll v) { tot++; e[tot].y=y; e[tot].v=v; e[tot].next=head[x]; head[x]=tot; } bool bfs() { memset(d,0,sizeof(d)); q.push(s); d[s]=1; while(q.size()) { int x=q.front(); q.pop(); for(int i=head[x];i;i=e[i].next) { if(e[i].v&&d[e[i].y]==0) { d[e[i].y]=d[x]+1; q.push(e[i].y); } } } return d[t]; } ll dfs(int x,ll flow) { if(x==t) return flow; ll sum=0; for(int i=head[x];i;i=e[i].next) { if(e[i].v&&d[e[i].y]==d[x]+1) { ll res=dfs(e[i].y,min(flow,e[i].v)); e[i].v-=res; e[i^1].v+=res; flow-=res; sum+=res; } } if(sum==0) d[x]=0; return sum; } int tx,ty; ll ans=0; int main() { freopen("1.in","r",stdin); n=read();m=read();s=read();t=read(); for(int i=1;i<=m;i++) { tx=read();ty=read(); add(tx,ty,read()); add(ty,tx,0); } while(bfs()) ans+=dfs(s,1e18); cout<<ans; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=110; struct edge { int y,next; ll v; }e[MAXN*2+MAXN*MAXN]; int head[MAXN],v[MAXN],d[MAXN]; int tot=1; int s,t; queue<int>q; void add(int x,int y,ll v) { tot++; e[tot].y=y; e[tot].v=v; e[tot].next=head[x]; head[x]=tot; } bool bfs() { memset(d,0,sizeof(d)); q.push(s); d[s]=1; while(q.size()) { int x=q.front(); q.pop(); for(int i=head[x];i;i=e[i].next) { if(e[i].v&&d[e[i].y]==0) { d[e[i].y]=d[x]+1; q.push(e[i].y); } } } return d[t]; } ll dfs(int x,ll flow) { if(x==t) return flow; ll sum=0; for(int i=head[x];i;i=e[i].next) { if(e[i].v&&d[e[i].y]==d[x]+1) { ll res=dfs(e[i].y,min(flow,e[i].v)); e[i].v-=res; e[i^1].v+=res; flow-=res; sum+=res; } } if(sum==0) d[x]=0; return sum; } int n,m,a,b; ll ans; int main() { //freopen("1.in","r",stdin); cin>>n>>m; s=0;t=n+1; for(int i=1;i<=m;i++) { add(s,i,1); add(i,s,0); } for(int i=m+1;i<=n;i++) { add(i,t,1); add(t,i,0); } while(cin>>a>>b) { add(a,b,1); add(b,a,0); } while(bfs()) ans+=dfs(s,1e18); cout<<ans; }
以下是原文
嗯,本文应该叫:网络流刷题柱.
差不多了,都是造福群众嘛~
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } const int oo=1000000; int n,m,a[300][300],sum=0,forward; bool vis[300],check=1; void dfs(int k,int l=oo) { vis[k]=1; if(k==n) { check=1; sum+=l; forward=l; return; } for(int i=1;i<=n;i++) { if((a[k][i]>0)&&(!vis[i])) { dfs(i,min(a[k][i],l)); if (check) { a[k][i]-=forward; a[i][k]+=forward; return; } } } } int main() { //freopen("123.in","r",stdin); m=read();n=read(); for(int i=1;i<=m;i++) { int x=read(),y=read(); a[x][y]+=read(); } while(check) { check=0; memset(vis,0,sizeof(vis)); dfs(1); } cout<<sum; return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } const int oo=1000000; int n,m,d,a[310][310],sum=0,forward; bool vis[310],check=1; void dfs(int k,int l=oo) { vis[k]=1; if(k==n+d+1) { check=1; sum+=l; forward=l; return; } for(int i=0;i<=n+d+1;i++) { if((a[k][i]>0)&&(!vis[i])) { dfs(i,min(a[k][i],l)); if (check) { a[k][i]-=forward; a[i][k]+=forward; return; } } } } int k; int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); n=read();k=read();d=read(); for(int i=1;i<=d;i++)//0 { a[i+n][d+n+1]+=read(); } for(int i=1;i<=n;i++)//0源点 1-n牛 d+n 菜 { int f=read(); //cout<<f<<endl; a[0][i]=k; for(;f;f--) a[i][read()+n]=1; } while(check) { check=0; memset(vis,0,sizeof(vis)); dfs(0); //cout<<sum<<endl; }/* for(int i=0;i<=d+n+1;i++) { for(int f=0;f<=d+n+1;f++) { if(a[i][f]) cout<<endl<<i<<' '<<f<<' '<<a[i][f]; } }*/ cout<<sum; return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } int n,m,inf=123456789; //int a[3010][3010],check,v[3010],forward,ans; int check,v[3010],forward,ans; struct edge { int y,v,next; }e[50010]; int tot,head[2010]; /* void dfs(int x,int l=inf) { //cout<<x<<endl; v[x]=1; if(x==n) { check=1; forward=l; ans+=l; return ; } for(int i=1;i<=2*n;i++) { if(a[x][i]>0&&!v[i]) { dfs(i,min(l,a[x][i])); if(check) { a[x][i]-=forward; a[i][x]+=forward; return ; } } } }*/ void add(int x,int y,int v=inf) { tot++; e[tot]=(edge){y,v,head[x]}; head[x]=tot; } void dfs(int x,int l=inf) { v[x]=1; if(x==n){ check=1; forward=l; ans+=l; return ; } for(int i=head[x];i;i=e[i].next) { if(e[i].v>0&&!v[e[i].y]) { dfs(e[i].y,min(l,e[i].v)); if(check) { e[i].v-=forward; e[i^1].v+=forward; return ; } } } } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); n=read();m=read();tot=1; for(register int i=2;i<n;i++) { add(i,i+n,1); add(i+n,i,1); /*a[i][i+n]=1; a[i+n][i]=1;*/ } for(;m;m--) { int tx=read(); int ty=read(); if(tx>ty) swap(tx,ty); if(tx==1) { //a[1][ty]=inf; add(1,ty); add(ty,1,0); } else if(ty==n) { //a[tx+n][n]=inf; //a[n][tx]=0; add(tx+n,n); add(n,tx+n,0); } else { /*a[tx+n][ty]=inf; a[ty+n][tx]=inf;*/ add(tx+n,ty); add(ty,tx+n,0); add(ty+n,tx); add(tx,ty+n,0); } } /*for(int i=1;i<=2*n;i++) for(int f=1;f<=2*n;f++) if(a[i][f]) cout<<i<<' '<<f<<' '<<a[i][f]<<endl;*/ /*for(int i=2;i<=tot;i++) { if(e[i].v) cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl; }*/ check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(1); } cout<<(ans==0?ans:ans-1);/*//cout<<' '<<clock();*/ }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } inline void write(int x){ if(x==0){ putchar('0'); return; } if(x<0){ putchar('-'); x=-x; } int num=0;char ch[16]; while(x) ch[++num]=x%10+'0',x/=10; while(num) putchar(ch[num--]); } int inf=987654321; int n,m,s[1010][25],ans=100000,/*a[1025][1025],*/head[1025],check,forward,v[1025],sum[25],G,tot; struct edge { int y,v,next; }e[200010]; void add(int x,int y,int v) { tot++; e[tot]=(edge){y,v,head[x]}; head[x]=tot; } void dfs(int x,int l=inf) { if(x==n+m+1) { check=1; forward=l; G+=l; return ; } v[x]=1; /*for(register int i=1;i<=n+m+1;i++) {*/ for(register int i=head[x];i;i=e[i].next) { if(e[i].v/*a[x][i]*/&&!v[e[i].y]) { dfs(e[i].y,min(l,e[i].v));//a[x][i])); if(check) { /*a[x][i]-=forward; a[i][x]+=forward;*/ e[i].v-=forward; e[i^1].v+=forward; return ; } } } } int main() { /*freopen("123.in","r",stdin); freopen("123.out","w",stdout);*/ n=read();m=read(); for(register int i=1;i<=n;i++) for(int f=1;f<=m;f++) s[i][f]=read(); for(register int i=1;i<=m;i++) sum[i]=read(); for(register int l=1;l<=m;l++) { for(register int r=l;l+ans-1>r&&r<=m;r++) { //memset(a,0,sizeof(a)); memset(head,0,sizeof(head)); tot=1; for(register int i=1;i<=n;i++) { //a[0][i]=1; add(0,i,1); add(i,0,0); for(register int f=l;f<=r;f++) //a[i][s[i][f]+n]=1; add(i,s[i][f]+n,1),add(s[i][f]+n,i,1); } for(register int i=1;i<=m;i++) //a[i+n][n+m+1]=sum[i]; add(i+n,n+m+1,sum[i]),add(n+m+1,i+n,0); G=0; check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(0); } if(G==n) { ans=min(ans,r-l+1); break; } } } cout<<ans; //cout<<' '<<clock(); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } inline void write(int x){ if(x==0){ putchar('0'); return; } if(x<0){ putchar('-'); x=-x; } int num=0;char ch[16]; while(x) ch[++num]=x%10+'0',x/=10; while(num) putchar(ch[num--]); } const int N=5010,M=200010; int head[N],d[N],incf[N],pre[N],v[N]; int n,m,k,tot,s,t,maxflow,ans; struct edge { int y,l,v,next; }e[M]; void add(int x,int y,int z,int c) { e[++tot].y=y;e[tot].l=z;e[tot].v=c; e[tot].next=head[x];head[x]=tot; e[++tot].y=x;e[tot].v=-c; e[tot].next=head[y];head[y]=tot; } int num(int i,int j,int k) { return (i-1)*m+j+k*n*m; } bool spfa() { queue<int>q; memset(d,0xcf,sizeof(d)); memset(v,0,sizeof(v)); q.push(s); d[s]=0; v[s]=1; incf[s]=1<<30; while(q.size()) { int x=q.front(); v[x]=0; q.pop(); for(int i=head[x];i;i=e[i].next) { if(!e[i].l)continue; int y=e[i].y; if(d[y]<d[x]+e[i].v) { d[y]=d[x]+e[i].v; incf[y]=min(incf[x],e[i].l); pre[y]=i; if(!v[y])v[y]=1,q.push(y); } } } if(d[t]==0xcfcfcfcf)return 0; return 1; } void update() { int x=t; while(x!=s) { int i=pre[x]; e[i].l-=incf[t]; e[i^1].l+=incf[t]; x=e[i^1].y; } maxflow+=incf[t]; ans+=d[t]*incf[t]; } int main() { //freopen("123.in","r",stdin); n=read();m=read(); k=2; tot=s=1,t=2*n*m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { int c=read(); add(num(i,j,0),num(i,j,1),1,c); add(num(i,j,0),num(i,j,1),k-1,0); if(j<m)add(num(i,j,1),num(i,j+1,0),k,0); if(i<n)add(num(i,j,1),num(i+1,j,0),k,0); } } while(spfa()) update(); write(ans); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } int inf=123456789,forward,check,ans,v[110]; int n,m,head[110],tot,can[1010],sum[1010]; //int e[10][10]; struct edge { int y,v,next; }e[100010]; void add(int x,int y,int v) { tot++; e[tot]=(edge){y,v,head[x]}; head[x]=tot; //e[x][y]=v; } void dfs(int x,int l=10*inf) { v[x]=1; if(x==n+1) { check=1; ans+=l; forward=l; return ; } for(register int i=head[x];i;i=e[i].next) { if(e[i].v>0&&!v[e[i].y]) { dfs(e[i].y,min(l,e[i].v)); if(check) { e[i].v-=forward; e[i^1].v+=forward; return ; } } } /* for(register int i=0;i<=n+1;i++) { if(a[x][i]>0&&!v[i]) { dfs(*/ } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); tot=1; m=read(); n=read(); for(register int i=1;i<=m;i++) sum[i]=read(); for(register int i=1;i<=n;i++) { for(register int A=read();A;A--) { int a=read(); if(can[a]) { add(can[a],i,inf); add(i,can[a],0); } else { add(0,i,sum[a]); add(i,0,0); } can[a]=i; } add(i,n+1,read()); add(n+1,i,0); } /*for(register int i=2;i<=tot;i++) { if(e[i].v) cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl; }*/ check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(0); } cout<<ans; /*for(register int i=2;i<=tot;i++) { if(e[i].v) cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl; }*/ }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } const int oo=1000000; int n,m,d,F,a[410][410],sum=0,forward; bool vis[410],check=1; void dfs(int k,int l=oo) { vis[k]=1; if(k==2*n+d+F+1) { check=1; sum+=l; forward=l; return; } for(int i=0;i<=2*n+d+F+1;i++) { if((a[k][i]>0)&&(!vis[i])) { dfs(i,min(a[k][i],l)); if (check) { a[k][i]-=forward; a[i][k]+=forward; return; } } } } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); n=read();F=read();d=read(); for(int i=1;i<=n;i++) { int f=read(),j=read(); for(;f;f--) { a[read()+2*n][i]=1; } for(;j;j--) { a[i+n][read()+2*n+F]=1; } a[i][i+n]=1; } for(int i=1;i<=F;i++) { a[0][i+2*n]=1; } for(int i=1;i<=d;i++) { a[i+2*n+F][d+2*n+F+1]=1; } while(check) { check=0; memset(vis,0,sizeof(vis)); dfs(0); } /*for(int i=0;i<=2*n+d+F+1;i++) { for(int f=0;f<=2*n+d+F+1;f++) { if(a[i][f]) { cout<<i<<' '<<f<<' '<<a[i][f]<<endl; } } }*/ cout<<sum; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } int inf=123456789; int n,m,c1,c2,a[210][210],b[210][210],v[210],check,forward,G,G0; void dfs(int x,int l=inf) { if(x==c2) { forward=l; check=1; G+=forward; return ; } v[x]=1; for(int i=1;i<=2*n;i++) { if(a[x][i]>0&&!v[i]) { dfs(i,min(l,a[x][i])); if(check) { a[x][i]-=forward; a[i][x]+=forward; return ; } } } } int main() { n=read();m=read();c1=read();c2=read(); if(c1>c2) swap(c1,c2); for(int i=1;i<=n;i++) if(i!=c1&&i!=c2) a[i][i+n]=1,a[i+n][i]=1; for(;m;m--) { int tx=read();int ty=read(); if(ty==c1) swap(tx,ty); if(tx==c2) swap(tx,ty); if(tx==c1) a[c1][ty]=inf; else if(ty==c2) a[tx+n][c2]=inf; else a[tx+n][ty]=1,a[ty+n][tx]=1; }//建图 memcpy(b,a,sizeof(a));//存边 check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(c1); } cout<<G<<endl;//跑出最小割 int sum=G0=G; for(int now=1;sum;now++)//枚举当前要删那个点 { if(now==c1||now==c2) continue; G=0; memcpy(a,b,sizeof(a)); for(int i=1;i<=2*n;i++) a[now][i]=a[i][now]=a[now+n][i]=a[i][now+n]=0; check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(c1); }//跑删掉这个点后的最小割 if(G<G0)//如果小于的话就更新G0,删边 { G0=G; cout<<now<<' '; sum--; for(int i=1;i<=2*n;i++) b[now][i]=b[i][now]=b[now+n][i]=b[i][now+n]=0; } } //cout<<clock(); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } inline void write(int x){ if(x==0){ putchar('0'); return; } if(x<0){ putchar('-'); x=-x; } int num=0;char ch[16]; while(x) ch[++num]=x%10+'0',x/=10; while(num) putchar(ch[num--]); } struct edge { int x,y,v,i; }e[1010]; bool v_(edge a,edge b) { return a.v>b.v; } int n,m,inf=987654321; int check,forward,a[40][40],b[40][40],G,G0,v[40]; void dfs(int x,int l=inf) { if(x==n) { check=1; forward=l; G+=l; return ; } v[x]=1; for(int i=1;i<=n;i++) { if(a[x][i]&&!v[i]) { dfs(i,min(l,a[x][i])); if(check) { a[x][i]-=forward; a[i][x]+=forward; return ; } } } } int sum; int main() { //freopen("123.in","r",stdin); n=read();m=read(); for(int i=1;i<=m;i++) { int tx=read(),ty=read(),tv=read(); e[i]=(edge){tx,ty,tv,i}; a[tx][ty]+=tv; sum+=tv; } sort(e+1,e+1+m,v_); memcpy(b,a,sizeof(a)); check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(1); } G0=G; write(G0); putchar(32); priority_queue<int>q; for(int i=1;i<=m;i++) { G=0; memcpy(a,b,sizeof(a)); a[e[i].x][e[i].y]-=e[i].v; check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(1); } if(G==G0-e[i].v) { q.push(-e[i].i); G0=G; b[e[i].x][e[i].y]-=e[i].v; } } write(q.size()); putchar(10); while(q.size()) { write(-q.top()); putchar(10); q.pop(); } return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } int inf=987654321; int head[1010],tot,d[1010]; int n,m,maxflow; queue<int>q; struct edge { int x,y,v,next; }e[1000010]; void add(int x,int y,int v) { tot++; e[tot].x=x; e[tot].y=y; e[tot].v=v; e[tot].next=head[x]; head[x]=tot; } bool bfs() { memset(d,0,sizeof(d)); while(q.size()) q.pop(); q.push(1);d[1]=1; while(q.size()) { int x=q.front();q.pop(); for(int i=head[x];i;i=e[i].next) { if(e[i].v&&!d[e[i].y]) { q.push(e[i].y); d[e[i].y]=d[x]+1; if(e[i].y==n)return 1; } } } return 0; } int dinic(int x,int flow) { if(x==n) return flow; int rest=flow,k; for(int i=head[x];i&&rest;i=e[i].next) { if(e[i].v&&d[e[i].y]==d[x]+1) { k=dinic(e[i].y,min(rest,e[i].v)); if(!k)d[e[i].y]=0; e[i].v-=k; e[i^1].v+=k; rest-=k; } } return flow-rest; } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); m=read();n=read(); //1=read();n=read(); tot=1; for(int i=1;i<=m;i++) { int tx=read(),ty=read(),tv=read(); add(tx,ty,tv); add(ty,tx,0); } int flow=0; while(bfs()) { while(flow=dinic(1,inf)) maxflow+=flow; } cout<<maxflow; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; /*char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; }*/ char temp; int n,m,a[60],tot,head[110],inf=987654321,forward,check,G,v[110],sum; struct edge { int x,y,v,next; }e[100000]; void add(int x,int y,int v=inf) { tot++; e[tot].x=x; e[tot].y=y; e[tot].v=v; e[tot].next=head[x]; head[x]=tot; } void dfs(int x,int l=inf) { v[x]=1; if(x==m+n+1) { forward=l; check=1; G+=forward; return ; } for(int i=head[x];i;i=e[i].next) { if(e[i].v>0&&!v[e[i].y]) { dfs(e[i].y,min(l,e[i].v)); if(check) { e[i].v-=forward; e[i^1].v+=forward; return ; } } } } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); cin>>m>>n; tot=1; for(int i=1;i<=m;i++) { int x; scanf("%d",&x); add(0,i,x); add(i,0,0); sum+=x; scanf("%c",&temp); while(temp!='\n') { int x; scanf("%d",&x); add(i,m+x); add(m+x,i,0); scanf("%c",&temp); } } for(int i=1;i<=n;i++) scanf("%d",&a[i]),add(m+i,m+n+1,a[i]),add(m+n+1,m+i,0); check=1; while(check) { check=0; memset(v,0,sizeof(v)); dfs(0); } cout<<sum-G; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } const int N=510,M=3010; int m,n,k,d[N],b[N][N],inf=987654321,o[N],v[N],head[N],tot,ans[N]; struct edge { int x,y,v,next; }e[M*3]; queue<int>q; void add(int x,int y,int v) { tot++; e[tot]=(edge){x,y,v,head[x]}; head[x]=tot; } bool bfs() { memset(d,0,sizeof(d)); while(q.size()) q.pop(); q.push(0);d[0]=1; while(q.size()) { int x=q.front();q.pop(); for(int i=head[x];i;i=e[i].next) { if(e[i].v&&!d[e[i].y]) { q.push(e[i].y); d[e[i].y]=d[x]+1; if(e[i].y==n+1) return 1; } } } return 0; } int dinic(int x,int flow) { if(x==n+1) return flow; int rest=flow,k; for(int i=head[x];i&&rest;i=e[i].next) { if(e[i].v&&d[e[i].y]==d[x]+1) { k=dinic(e[i].y,min(rest,e[i].v)); if(!k) d[e[i].y]=0; e[i].v-=k; e[i^1].v+=k; rest-=k; } } return flow-rest; } void get(int now,int move) { v[now]=1; ans[now]|=(1<<move); for(int i=head[now];i;i=e[i].next) if(e[i].v&&!v[e[i].y]) get(e[i].y,move); } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); n=read();m=read(); for(int i=1;i<=m;i++) { int x=read();int y=read(); b[x][y]=b[y][x]=1; } k=read(); for(int i=1;i<=k;i++) { o[i]=read(); ans[o[i]]=read(); } for(int i=0;i<=31;i++) { memset(head,0,sizeof(head)); tot=1; for(int now=1;now<=k;now++) { if((1<<i)&ans[o[now]]) { add(0,o[now],inf); add(o[now],0,0); } else { add(o[now],n+1,inf); add(n+1,o[now],0); } } for(int f=1;f<=n;f++) { for(int j=1;j<=n;j++) { if(b[f][j]) { add(f,j,1); add(j,f,1); } } } /*if((1<<i)==8) for(int j=1;j<=tot;j++) { if(e[j].v) cout<<e[j].x<<' '<<e[j].y<<' '<<e[j].v<<endl; }*/ int flow; while(bfs()) { flow=1; while(flow) { flow=dinic(0,inf); } } memset(v,0,sizeof(v)); get(0,i); } for(int i=1;i<=n;i++) cout<<ans[i]<<endl; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> using namespace std; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } const double eps=1e-4; double min(double a,double b) { return a>b?b:a; } double inf=987654321; int n,m,head[1200],tot,d[1200],v[1200]; struct edge{ int x,y,next; double v; }e[10000]; struct node{ int a,b; }o[10000]; void add(int x,int y,double v=inf){ tot++; e[tot]=(edge){x,y,head[x],v}; head[x]=tot; } bool bfs(){ memset(d,0,sizeof(d)); queue<int>q; q.push(0);d[0]=1; while(q.size()) { int x=q.front();q.pop(); for(int i=head[x];i;i=e[i].next) if(e[i].v>=eps&&!d[e[i].y]) { q.push(e[i].y); d[e[i].y]=d[x]+1; if(e[i].y==n+m+1) return 1; } } return 0; } double dinic(int x,double flow){ if(x==n+m+1) return flow; double rest=flow,k; for(int i=head[x];i&&rest>=eps;i=e[i].next) if(e[i].v>=eps&&d[e[i].y]==d[x]+1) { k=dinic(e[i].y,min(rest,e[i].v)); if(k<eps) d[e[i].y]=0; e[i].v-=k; e[i^1].v+=k; rest-=k; if(rest<eps) return flow-rest; } return flow-rest; } int main() { //freopen("123.in","r",stdin); //freopen("123.out","w",stdout); n=read();m=read(); for(int i=1;i<=m;i++) o[i]=(node){read(),read()}; double l=0,r=m,mid; while(l+1e-4<r) { mid=(l+r)/2; tot=1; memset(head,0,sizeof(head)); for(int i=1;i<=m;i++) { add(0,i+n,1); add(i+n,0,0); add(i+n,o[i].a); add(o[i].a,i+n,0); add(i+n,o[i].b); add(o[i].b,i+n,0); } for(int i=1;i<=n;i++) add(i,n+m+1,mid),add(n+m+1,i,0); /*for(int i=1;i<=tot;i++) { if(e[i].v) cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl; }*/ double G=0,flow=0; while(bfs()) { while((flow=dinic(0,inf))>eps) G+=flow; } if(m-G>0) l=mid; else r=mid; } cout<<setiosflags(ios::fixed)<<setprecision(3); cout<<l; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<iomanip> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<string> #include<algorithm> #include<vector> #include<map> #include<stack> #include<complex> #include<queue> #include<deque> #include<set> #include<bitset> #define eps 1e-12 using namespace std ; char buf[1<<15],*fs,*ft; inline char getc(){ return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++; } inline int read(){ int This=0,F=1; char ch=getc(); while(ch<'0'||ch>'9'){ if(ch=='-') F=-1; ch=getc(); } while(ch>='0'&&ch<='9'){ This=(This<<1)+(This<<3)+ch-'0'; ch=getc(); } return This*F; } struct edge { int x,y; double v; int next ; }e[10000],p[1200]; int head[120],tot,inf=987654321; int d[120],n,m,con[120]; int vis[120],num; queue<int>q; void add(int x,int y,double v) { tot++; e[tot]=(edge){x,y,v,head[x]}; head[x]=tot; } int bfs() { memset(d,0,sizeof(d)); d[0]=1; q.push(0); while(!q.empty()) { int x=q.front();q.pop(); for(register int i=head[x];i;i=e[i].next) { if(!d[e[i].y]&&e[i].v>=eps) { d[e[i].y]=d[x]+1 ; q.push(e[i].y); } } } if(d[n+1]>0) return 1 ; return 0 ; } double dinic(int x,double flow) { if(x==n+1) return flow; double rest=flow,k; for(register int i=head[x];i&&rest>eps;i=e[i].next) { if(e[i].v>eps&&d[e[i].y]==d[x]+1) { k=dinic(e[i].y,min(rest,e[i].v)); if(k<eps) d[e[i].y]=0; e[i].v-=k; e[i^1].v+=k; rest-=k; } } return flow-rest; } double ask(double k) { memset(head,0,sizeof(head)); tot=1; double temp,max_flow=0; for(register int i=1;i<=m;i++) { add(p[i].x,p[i].y,1.0); add(p[i].y,p[i].x,1.0); } for(register int i=1;i<=n;i++) { add(0,i,m); add(i,0,0); add(i,n+1,m+2*k-con[i]); add(n+1,i,0); } while(bfs()) while((temp=dinic(0,m))>=eps) max_flow+=temp ; return ((double)m*n-max_flow)/2; } int main() { //freopen("123.in","r",stdin); //freopen("123.out","v",stdout); n=read();m=read(); for(register int i=1;i<=m;i++) { p[i].x=read();p[i].y=read(); con[p[i].x]++; con[p[i].y]++; } double l,r,mid,temp; l=0;r=m; while(r-l>=1e-4) { mid=(l+r)/2; temp=ask(mid); if(temp>=eps) l=mid; else r=mid; } cout<<setiosflags(ios::fixed)<<setprecision(3); cout<<l; }
网络流最难的是建图.我就把建图说一下好了.
p1318
裸的最大流吧.对于每个边都把邻接矩阵+=v.
跑最大流.
p1319
和p1324有点像啊...
令0为源点,1-n为牛,n+1到n+d为菜,n+d+1为汇点.
每个菜向汇点连一条权值为菜的数量的边,从源点向每个牛连一条权值为这个牛会做的菜的数量的边(权值也可以为inf),每个牛向它所有能做的菜连一条权值为1的边.
跑最大流.
p1320.
无向图,求至少割几个点使得1到n不连通.输出答案减一.
把点拆成i和i+n,连双向边,流量都是1.
对于图中的边,如果是(1,y)这样的形式就连1到y.如果是(x,n)这样的形式就连x+n,n.否则对于(x,y),连(x+n,y)和(y+n,x).这些都是单向边且流量为inf.我们还需要建一个反向边以供增广.
然后从1往外跑最大流.输出最大流>0?最大流-1:最大流.
p1325
要求"郁闷指数跨度"最小.
可以每次枚举郁闷指数的左右区间,令源点到牛们连一条流量为1的边,牛向当前枚举到的区间里的牛棚连一条流量为1的边,再从牛棚向汇点连一条长为牛棚容量限制的边,
虽然可以二分,但是写了个小优化就过去了,最慢的也不过265ms.
p1670
水了个n^4dp,以后再填坑.
2333
康神tql.
当只能走一遍的时候,我们可以跑一遍最短路完事~.
否则就是一个同时有权值和限制的最优化问题.也就是最大费用最大流.
继续拆点,令入点为1-n^2,n^2+1-2n^2为出点.每个格子从入点到出点连两条边:第一条容量为1,费用为到达这个格子的"好心程度",第二条容量为1,费用为0.每个格子的出点向右边和下边的格子的入点连一条容量为2,费用为0的边.
然后开始跑最大费用最大流.
p1609
令0为源点,1-n为顾客,n+1为汇点.
先把猪圈里猪的数量存起来.
维护每个猪圈最后一次是被哪个顾客打开的.对于每个顾客能打开的猪圈,如果之前有顾客打开过就从上一个顾客连一条流量为inf的边,否则从源点向顾客连一条流量为该猪圈里猪的数量的边.最后向汇点连一条流量为需求的边.更新"最后一次是被哪个顾客打开的".
p1324
把点拆成1-n和n+1到2*n,令0为源点,2*n+1-2*n+F为食品,2*n+F+1到2*n+F+d为饮料,2*n+F+d+1为汇点.先连边i到i+n约束牛,汇点连食品,饮料们连源点. 对于牛i,食品连i,i+n连饮料.以上边权都为1.
p1342
p1320的加强版.拆点后跑最大流.记录当前最大流为G0.为了输出字典序最小字典序的方案,从小到大枚举所有的点,假装删掉这个点,看最大流G是否小于G0.如果小于说明是可以删掉它,更新G0,真的删掉这个点.否则把那些边还回去...
p1341
第一问是正经的最小割.设最大流为G0.
第二问类比上一题(果然应该先写上一题).为了最小化,我们按边权枚举所有的边,尝试着删去后看最大流G是否刚好减少了v.如果刚好减少了v就放入一个堆里,把边删掉,更新G0.否则继续.
p1671=p1318
终于还是学了dinic...
p1343
最大权闭合子图.
一个有n个点的点权和m条边的网络流图,求闭合子图中点权和最大的那个点权和.
我们原图保持不变,但是边权设为inf表示不可割.从S向所有点权为正的边连一条边权为点权的边,从所有点权为负的点向T连一条边权为点权的边.然后跑最小割即最大流.最大点权和即为正点权和-最大流.
为什么可以这样做呢?可以从最小割的角度来理解.
考虑最小割的实际意义:表示我不要这个边了,那么在原图中就表示为不要这个点了.或实验,或仪器.如果把实验的那个边删了表示放弃了这个实验的收益,如果把仪器那边删了表示不需要这个仪器,那么那边的实验就做不了了.
p1349
p1672
找到了一个贪心的算法,非常的厉害.
p1673
看上去是很裸的最小费用最大流.
拿到题当然要先分析题意.然后,先不管费用,建一个符合题意的最大流模型.
发现要满足每天有ni个毛巾,于是就想到了拆点建图.
根据题意这样建图好像没什么问题.
但是一会要跑最小费用最大流了,但是i+n到i+a的那些边是用不到的,因为
源点向1-i连一条容量为need[i],费用为f的边表示这天直接买了多少的新毛巾,花费为f.然后连一条连向汇点,费用为为0的边.