【图】网络流ISAP

来源:互联网 发布:unity3d vr抗锯齿 编辑:程序博客网 时间:2024/05/18 01:45
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);  }};

另一个模板

#include <iostream>#include <cstdio>#include <climits>#include <cstring>#include <algorithm>using namespace std;typedef  struct {int v,next,val;} edge;const int MAXN=20010;const int MAXM=500010;edge e[MAXM];int p[MAXN],eid;inline void init(){memset(p,-1,sizeof(p));eid=0;}//有向inline void insert1(int from,int to,int val){    e[eid].v=to;e[eid].val=val;    e[eid].next=p[from];    p[from]=eid++;    swap(from,to);    e[eid].v=to;e[eid].val=0;    e[eid].next=p[from];    p[from]=eid++;}//无向inline void insert2(int from,int to,int val){    e[eid].v=to;e[eid].val=val;    e[eid].next=p[from];    p[from]=eid++;    swap(from,to);    e[eid].v=to;e[eid].val=val;    e[eid].next=p[from];    p[from]=eid++;}int n,m;//n为点数 m为边数int h[MAXN];int gap[MAXN];int source,sink;inline int dfs(int pos,int cost){    if (pos==sink) return cost;    int j,minh=n-1,lv=cost,d;    for (j=p[pos];j!=-1;j=e[j].next)    {        int v=e[j].v,val=e[j].val;        if(val>0)        {            if (h[v]+1==h[pos])            {                if (lv<e[j].val) d=lv;                else d=e[j].val;                d=dfs(v,d);                e[j].val-=d;                e[j^1].val+=d;                lv-=d;                if (h[source]>=n) return cost-lv;                if (lv==0) break;            }            if (h[v]<minh)    minh=h[v];        }    }    if (lv==cost)    {        --gap[h[pos]];        if (gap[h[pos]]==0) h[source]=n;        h[pos]=minh+1;        ++gap[h[pos]];    }    return cost-lv;}int isap(int st,int ed){    source=st;sink=ed;    int ret=0;    memset(gap,0,sizeof(gap));    memset(h,0,sizeof(h));    gap[st]=n;    while (h[st]<n)    {        ret+=dfs(st,INT_MAX);    }    return ret;}int main(){    while(cin>>m>>n)    {        init();        for(int i=0;i<m;i++)        {            int u,v,c;            scanf("%d%d%d",&u,&v,&c);            insert1(u,v,c);        }        printf("%d\n",isap(1,n));    }    return 0;}



0 0
原创粉丝点击