标准的大白书式模板,除了变量名并不一样……在主函数中只需要用到 init 函数、add 函数以及 mf 函数
1 #include<stdio.h> //差不多要加这么些头文件 2 #include<string.h> 3 #include<queue> 4 #include<vector> 5 #include<algorithm> 6 using namespace std; 7 const int maxm=150+5; //点的总数 8 const int INF=0x3f3f3f3f; 9 10 struct edge{ //弧的结构体,变量:弧的出发点、结束点、容量、流量 11 int from,to,c,f; 12 edge(int a,int b,int m,int n):from(a),to(b),c(m),f(n){} 13 }; 14 15 struct dinic{ 16 int m,s,t; //边数、源点标号、汇点标号 17 vector<edge>e; //边 18 vector<int>g[maxm]; //g[i][j]表示第i个点出发的第j条边在e中的编号 19 bool vis[maxm]; 20 int d[maxm],cur[maxm]; //d为源点到点的距离,cur为当前遍历到的边 21 void init(int n){ 初始化,n为点数量(标号0~n-1) 22 for(int i=0;i<n+5;i++)g[i].clear(); 23 e.clear(); 24 } 25 void add(int a,int b,int v){ //加入弧和反向弧 26 e.push_back(edge(a,b,v,0)); //正向弧容量v,反向弧容量0 27 e.push_back(edge(b,a,0,0)); 28 m=e.size(); 29 g[a].push_back(m-2); 30 g[b].push_back(m-1); 31 } 32 bool bfs(){ 33 memset(vis,0,sizeof(vis)); 34 queue<int>q; 35 q.push(s); 36 d[s]=0; 37 vis[s]=1; 38 while(!q.empty()){ 39 int u=q.front();q.pop(); 40 for(int i=0;i<g[u].size();i++){ 41 edge tmp=e[g[u][i]]; 42 if(!vis[tmp.to]&&tmp.c>tmp.f){ 43 vis[tmp.to]=1; 44 d[tmp.to]=d[u]+1; 45 q.push(tmp.to); 46 } 47 } 48 } 49 return vis[t]; 50 } 51 int dfs(int x,int a){ 52 if(x==t||a==0)return a; 53 int flow=0,f; 54 for(int& i=cur[x];i<g[x].size();i++){ 55 edge &tmp=e[g[x][i]]; 56 if(d[x]+1==d[tmp.to]&&(f=dfs(tmp.to,min(a,tmp.c-tmp.f)))>0){ 57 tmp.f+=f; 58 e[g[x][i]^1].f-=f; 59 flow+=f; 60 a-=f; 61 if(a==0)break; 62 } 63 } 64 if(!flow)d[x]=-1; 65 return flow; 66 } 67 int mf(int s,int t){ 在主函数中使用的函数,求s到t的最大流 68 this->s=s; 69 this->t=t; 70 int flow=0; 71 while(bfs()){ 72 memset(cur,0,sizeof(cur)); 73 flow+=dfs(s,INF); 74 } 75 return flow; 76 } 77 }; 78
时间: 2024-10-26 10:29:03