最大流模板

来源:互联网 发布:ubuntu安装openstack 编辑:程序博客网 时间:2024/05/22 09:40

Dinic算法-------来自LRJ

struct Edge{    int from, to, cap, flow;};struct Dinic{    int n, m ,s, t;    vector<Edge> edges;    VI G[maxn];    bool vis[maxn];    int d[maxn];    int cur[maxn]   ;    void init(int nn)    {        this->n = nn;        REP(i, n + 2) G[i].clear();        edges.clear();    }    void addEdge(int from, int to, int cap)    {        edges.PB((Edge){from, to, cap, 0});        edges.PB((Edge){to, from, 0, 0});        m = edges.size();        G[from].PB(m - 2);        G[to].PB(m - 1);    }    bool bfs()    {        CLR(vis, 0);        queue<int> Q;        Q.push(s);        d[s] = 0;        vis[s] = 1;        while (!Q.empty())        {            int x = Q.front();            Q.pop();            REP(i, G[x].size())            {                Edge& e = edges[G[x][i]];                if (!vis[e.to] && e.cap > e.flow)                {                    vis[e.to] = 1;                    d[e.to] = d[x] + 1;                    Q.push(e.to);                }            }        }        return vis[t];    }    int dfs(int x, int a)    {        if (x == t || a == 0)   return a;        int flow = 0, f;        for (int& i = cur[x]; i < G[x].size(); i++)        {            Edge& e = edges[G[x][i]];            if (d[x] + 1 == d[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0)            {                e.flow += f;                edges[G[x][i] ^ 1].flow -= f;                flow += f;                a -= f;                if (a == 0) break;            }        }        return flow;    }    //当所求流量大于need时就退出,降低时间    int maxflow(int s,int t,int need){        this->s = s; this->t = t;        int flow = 0;        while(bfs())        {            CLR(cur ,0);            flow += dfs(s,INF);            if (flow > need)                return flow;        }        return flow;    }    //最小割割边    vector<int> Mincut(){        BFS();        vector<int> ans;        for (int i = 0; i < edges.size(); i++){            Edge& e = edges[i];            if (vis[e.from] && !vis[e.to] && e.cap > 0)        ans.push_back(i);        }        return ans;    }    void Reduce(){        for(int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow;    }    void ClearFlow(){        for(int i = 0; i < edges.size(); i++) edges[i].flow = 0;    }}sol;

ISAP最大流,效率高于Dinic

//ISAPstruct Edge {  int from, to, cap, flow;};bool operator < (const Edge& a, const Edge& b) {  return a.from < b.from || (a.from == b.from && a.to < b.to);}struct ISAP {  int n, m, s, t;  vector<Edge> edges;  vector<int> G[maxn];   // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号  bool vis[maxn];        // BFS使用  int d[maxn];           // 从起点到i的距离  int cur[maxn];        // 当前弧指针  int p[maxn];          // 可增广路上的上一条弧  int num[maxn];        // 距离标号计数  void AddEdge(int from, int to, int cap) {    edges.push_back((Edge){from, to, cap, 0});    edges.push_back((Edge){to, from, 0, 0});    m = edges.size();    G[from].push_back(m-2);    G[to].push_back(m-1);  }  bool BFS() {    memset(vis, 0, sizeof(vis));    queue<int> Q;    Q.push(t);    vis[t] = 1;    d[t] = 0;    while(!Q.empty()) {      int x = Q.front(); Q.pop();      for(int i = 0; i < G[x].size(); i++) {        Edge& e = edges[G[x][i]^1];        if(!vis[e.from] && e.cap > e.flow) {          vis[e.from] = 1;          d[e.from] = d[x] + 1;          Q.push(e.from);        }      }    }    return vis[s];  }  void ClearAll(int n) {    this->n = n;    for(int i = 0; i < n; i++) G[i].clear();    edges.clear();  }  void ClearFlow() {    for(int i = 0; i < edges.size(); i++) edges[i].flow = 0;  }  int Augment() {    int x = t, a = INF;    while(x != s) {      Edge& e = edges[p[x]];      a = min(a, e.cap-e.flow);      x = edges[p[x]].from;    }    x = t;    while(x != s) {      edges[p[x]].flow += a;      edges[p[x]^1].flow -= a;      x = edges[p[x]].from;    }    return a;  }  int Maxflow(int s, int t, int need) {    this->s = s; this->t = t;    int flow = 0;    BFS();    memset(num, 0, sizeof(num));    for(int i = 0; i < n; i++) num[d[i]]++;    int x = s;    memset(cur, 0, sizeof(cur));    while(d[s] < n) {      if(x == t) {        flow += Augment();        if(flow >= need) return flow;        x = s;      }      int ok = 0;      for(int i = cur[x]; i < G[x].size(); i++) {        Edge& e = edges[G[x][i]];        if(e.cap > e.flow && d[x] == d[e.to] + 1) { // Advance          ok = 1;          p[e.to] = G[x][i];          cur[x] = i; // 注意          x = e.to;          break;        }      }      if(!ok) { // Retreat        int m = n-1; // 初值注意        for(int i = 0; i < G[x].size(); i++) {          Edge& e = edges[G[x][i]];          if(e.cap > e.flow) m = min(m, d[e.to]);        }        if(--num[d[x]] == 0) break;        num[d[x] = m+1]++;        cur[x] = 0; // 注意        if(x != s) x = edges[p[x]].from;      }    }    return flow;  }  vector<int> Mincut() { // call this after maxflow    BFS();    vector<int> ans;    for(int i = 0; i < edges.size(); i++) {      Edge& e = edges[i];      if(!vis[e.from] && vis[e.to] && e.cap > 0) ans.push_back(i);    }    return ans;  }  void Reduce() {    for(int i = 0; i < edges.size(); i++) edges[i].cap -= edges[i].flow;  }  void print() {    printf("Graph:\n");    for(int i = 0; i < edges.size(); i++)      printf("%d->%d, %d, %d\n", edges[i].from, edges[i].to , edges[i].cap, edges[i].flow);  }};


原创粉丝点击