POJ-1698-网络流最大流构图

来源:互联网 发布:java算法 编辑:程序博客网 时间:2024/05/18 15:25

题目大意:有m个猪圈,有n个客户来卖猪,每个人有相应的钥匙,并且买完后可以重新组合新的猪圈,问最后最多可以卖掉多少?

题目解析:因为是有顺序的,所以遍历每个客户所对应的猪圈的时候,如果该猪圈没有被打开过m,就连一条a[i]的边,如果被打开过,就从上一个打开的客户连向这个客户,值为inf,最后每个客户指向汇点即可;

AC代码:

#include<iostream>  #include<cstdio>  #include<algorithm>  #include<cstring>  #include<string>  #include<vector>  #include<queue>using namespace std;  const int inf=0x3fffffff;  const int maxn=1010;  struct node  {      int to,cap,rev;       node(int a,int b,int c)      {          to=a;          cap=b;          rev=c;      }  };  vector<node>vec[maxn];    int pre[maxn],iter[maxn];bool vis[maxn];void add_edge(int from,int to,int cost)  {      vec[from].push_back(node(to,cost,vec[to].size()));      vec[to].push_back(node(from,0,vec[from].size()-1));  }  void bfs(int s){      memset(pre,-1,sizeof(pre));      queue<int>que;      pre[s]=0;que.push(s);      while(!que.empty()){          int v=que.front();que.pop();          for(int i=0;i<vec[v].size();i++){              node &e=vec[v][i];              if(e.cap>0&&pre[e.to]<0){                  pre[e.to]=pre[v]+1;                  que.push(e.to);              }          }      }  }  int dfs(int v,int t,int f){      if(v==t) return f;      for(int &i=iter[v];i<vec[v].size();i++){          node &e=vec[v][i];          if(e.cap>0&&pre[v]<pre[e.to]){              int d=dfs(e.to,t,min(f,e.cap));              if(d>0){                  e.cap-=d;                  vec[e.to][e.rev].cap+=d;                  return d;              }          }      }      return 0;  }  int max_flow(int u,int v)  {      int flow=0;      while(1)          {          bfs(u);        if(pre[v]<0)    return flow;        memset(iter,0,sizeof(iter));          int f;          while((f=dfs(u,v,inf))>0) flow+=f;      }  }  int main()  {      int n,m,a[1010],t,temp,i,last[1010],u;    while(scanf("%d%d",&m,&n)!=EOF)    {    for(i=0;i<maxn;i++)    vec[i].clear();    for(i=1;i<=m;i++)    {    scanf("%d",&a[i]);    }    memset(vis,0,sizeof(vis));    for(i=1;i<=n;i++)    {    scanf("%d",&t);    while(t--)    {    scanf("%d",&u);    if(!vis[u])    {    vis[u]=1;    add_edge(0,i,a[u]);    last[u]=i;    }    else     {    add_edge(last[u],i,inf);    last[u]=i;    }    }    scanf("%d",&t);    add_edge(i,n+1,t);    }    printf("%d\n",max_flow(0,n+1));    }    return 0;  }  


0 0