之前写好的网络流笔记没有保存,不见了,懒得弄了,直接贴代码了
什么时候闲了再回来搞吧
//科学计数法:2e9 //1dfs //其实我是有一点拿网络流练dfs的意思的 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; const int inf=2e9; int n,m,s,ed;//明确了以后用ed表示终点 const int N=10003,M=100003;//这里主要看N的大小,N不大就用邻接矩阵,N太大N^2就会MLE,用邻接表 int head[N],tot=1; struct node { int v,w,nx; }e[M<<1];//双向边 void add(int u,int v,int w) { e[++tot].v =v,e[tot].w =w,e[tot].nx =head[u],head[u]=tot; e[++tot].v =u,e[tot].w =0,e[tot].nx =head[v],head[v]=tot;//这里把反向边的值设置成0,防止反向走边 } bool vis[N]; int dfs(int x,int flow) { for(int i=head[x];i;i=e[i].nx ) { int v=e[i].v ,w=e[i].w ; if(vis[v] || w<=0) continue; vis[v]=true; int t=min(flow,w),tt; if(v==ed) { e[i].w -=t,e[i^1].w +=t; return t; } else if( (tt=dfs(v,t))>0 )//夭寿咯 { e[i].w -=tt; e[i^1].w +=tt; return tt; } } return 0; } int ans; int main() { scanf("%d%d%d%d",&n,&m,&s,&ed); int u,v,w; while(m--) scanf("%d%d%d",&u,&v,&w),add(u,v,w); //练习dfs剪枝啦~~ int ttt=0; while((memset(vis,false,sizeof(vis)) &&(vis[s]=true) ) && ( ttt=dfs(s,inf))>0)//夭寿咯 ans+=ttt; printf("%d",ans); return 0; }
//FF算法 //1 dfs 1.09s //2 bfs 330s #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int inf=2e9; int n,m,s,ed;//明确了以后用ed表示终点 const int N=10003,M=100003;//这里主要看N的大小,N不大就用邻接矩阵,N太大N^2就会MLE,用邻接表 int head[N],tot=1; struct node { int v,w,nx; }e[M<<1];//双向边 void add(int u,int v,int w) { e[++tot].v =v,e[tot].w =w,e[tot].nx =head[u],head[u]=tot; e[++tot].v =u,e[tot].w =0,e[tot].nx =head[v],head[v]=tot;//这里把反向边的值设置成0,防止反向走边 } int pre[N];//作用更大的vis标记 int flow[N];//没有dfs一整条路径来记,每个点的flow只能自己记着 int ans; void bfs() { queue <int> q; while(1) { memset(pre,0,sizeof(pre)); memset(flow,0,sizeof(flow));//清空 //找边 pre[s]=-1,flow[s]=inf;//这里的pre不能是0,否则会被遍历到 //flow依旧设成无限大 while(!q.empty() ) q.pop() ; q.push(s); while(!flow[ed] && !q.empty() ) { int u=q.front() ;q.pop() ; for(int i=head[u];i;i=e[i].nx ) { int v=e[i].v ; if(!flow[v] && e[i].w >0) pre[v]=i,flow[v]=min(flow[u],e[i].w ),q.push(v); } } if(!flow[ed]) break; //没有增广路就退出 ans+=flow[ed]; int pos=pre[ed],tt=flow[ed]; while( pos >0)//注意!!!夭寿咯 { e[pos].w -=tt; e[pos^1].w +=tt; pos=pre[e[pos^1].v ]; } } printf("%d",ans); } int main() { scanf("%d%d%d%d",&n,&m,&s,&ed); int u,v,w; while(m--) scanf("%d%d%d",&u,&v,&w),add(u,v,w); //bfs加速搜索啦~~ bfs(); return 0; }
//3dinic 154ms #include<cstdio> #include<cstdlib> #include<queue> #include<cstring> using namespace std; int n,m,s,ed; const int N=10003,M=100003,inf=2e9; struct node { int v,w,nx; }e[M<<1]; int tot=1,head[N]; void add(int u,int v,int w) { e[++tot].v =v,e[tot].w =w,e[tot].nx =head[u],head[u]=tot; } int cur[N],dep[N],depth; int bfs() { memset(dep,0,sizeof(dep)); dep[s]=1; queue <int> q; q.push(s); while(!dep[ed] && !q.empty() ) { int u=q.front() ;q.pop() ; for(int i=head[u];i;i=e[i].nx ) { int v=e[i].v ; if(!dep[v] && e[i].w >0) dep[v]=dep[u]+1,q.push(v); } } return depth=dep[ed]; } int dfs(int x,int flow) { int ans=0; if(x==ed) return flow; if(!dep[x] || dep[x]>depth) return 0; for(int i=head[x];i;i=e[i].nx ) { int v=e[i].v ; if(dep[v]==dep[x]+1 && e[i].w >0) { int t=dfs(v,min(flow,e[i].w )); e[i].w -=t; e[i^1].w +=t; flow-=t,ans+=t; } if(!flow) break; } if(!ans) dep[x]=0; return ans; } int aans; int main() { scanf("%d%d%d%d",&n,&m,&s,&ed); int u,v,w; while(m--) scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,0); while(bfs()) aans+=dfs(s,inf); printf("%d ",aans); return 0; }