ISAP模板

来源:互联网 发布:c语言字母大小写转换 编辑:程序博客网 时间:2024/05/19 04:27
#include<bits/stdc++.h>  //#pragma comment(linker, "/STACK:1024000000,1024000000")   #include<stdio.h>  #include<algorithm>  #include<queue>  #include<string.h>  #include<iostream>  #include<math.h>  #include<set>  #include<map>  #include<vector>  #include<iomanip>  using namespace std;  #define ll long long  #define pb push_back  #define FOR(a) for(int i=1;i<=a;i++)  const int inf=0x3f3f3f3f;  const int maxn=1e6+9;      int num_nodes;  //预留超级源给0,所有的点是0到num_nodes-1int tot;  int d[maxn],cur[maxn],source,sink;  int p[maxn],num[maxn],vis[maxn];    struct EDGE{      int from,to,cap,flow;  };  vector<EDGE>edge;  vector<int>G[maxn];    void init(){      edge.clear();      for(int i=0;i<maxn;i++)G[i].clear();  }    void addedge(int u,int v,int w){      edge.push_back((EDGE){u,v,w,0});      edge.push_back((EDGE){v,u,0,0});      tot=edge.size();      G[u].push_back(tot-2);      G[v].push_back(tot-1);  }    int bfs(){      //只跑一次初始化原图层次,void也行    memset(vis,0,sizeof vis);      queue<int>Q;      Q.push(sink);      vis[sink]=1;      d[sink]=0;      while(!Q.empty()){          int u=Q.front();          Q.pop();          int sz=G[u].size();          for(int i=0;i<sz;++i){              EDGE &e=edge[G[u][i]^1];              if(!vis[e.from] && e.cap>e.flow){                  vis[e.from]=1;                  d[e.from]=d[u]+1;                  Q.push(e.from);              }          }      }      return vis[source];  }    int augment(){  //遍历处理出的路径    int u=sink,a=inf;      while(u!=source){          EDGE &e=edge[p[u]];          a=min(a,e.cap-e.flow);          u=edge[p[u]].from;      }      u=sink;      while(u!=source){          edge[p[u]].flow+=a;          edge[p[u]^1].flow-=a;          u=edge[p[u]].from;      }      return a;  }    int maxflow(){      int flow=0;      bfs();             //处理出d数组表示层次图     memset(num,0,sizeof num);      for(int i=0;i<num_nodes;i++)num[d[i]]++;    //各个层次的点有多少个      int u=source;      memset(cur,0,sizeof cur);              //当前弧编号,前面不行后面也不会用    while(d[source]<num_nodes){          //残量网络可达        if(u==sink){                      //增广到终点            flow+=augment();              u=source;          }          bool advance=false;          int sz=G[u].size();          for(int i=cur[u];i<sz;i++){              EDGE &e=edge[G[u][i]];              if(e.cap>e.flow && d[u]==d[e.to]+1){                  advance=true;                  p[e.to]=G[u][i];                  cur[u]=i;                  u=e.to;                  break;              }          }          if(!advance){              int m=num_nodes-1;              int sz=G[u].size();              for(int i=0;i<sz;i++){                  if(edge[G[u][i]].cap>edge[G[u][i]].flow){                      m=min(m,d[edge[G[u][i]].to]);                  }                         }              if(--num[d[u]]==0)break;              num[d[u]=m+1]++;              cur[u]=0;              if(u!=source)u=edge[p[u]].from;          }      }      return flow;  }  /******main:init(),num_nodes,source,sink******/

原创粉丝点击