[网络流] 2016 计蒜之道 复赛 菜鸟物流的运输网络

来源:互联网 发布:淘宝网网上购物手机 编辑:程序博客网 时间:2024/05/01 00:01

网络流模型 拆点卡流量


#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#define cl(x) memset(x,0,sizeof(x))using namespace std;inline char nc(){  static char buf[100000],*p1=buf,*p2=buf;  if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }  return *p1++;}inline void read(int &x){  char c=nc(),b=1;  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}#define V G[p].vnamespace DINIC{  const int N=505;  const int M=100005;  struct edge{    int u,v,f,next;  }G[M<<1];  int head[N],inum=1;  inline void add(int u,int v,int f,int p){    G[p].u=u; G[p].v=v; G[p].f=f; G[p].next=head[u]; head[u]=p;  }  inline void link(int u,int v,int f){    add(u,v,f,++inum); add(v,u,0,++inum);  }  inline void clear(){    cl(head); inum=1;  }  int S,T;  int Q[N],l,r;  int dis[N];  inline bool bfs(){    memset(dis,-1,sizeof(dis)); dis[S]=1;    l=r=-1; Q[++r]=S;    while (l<r){      int u=Q[++l];      for (int p=head[u];p;p=G[p].next)if (G[p].f && dis[V]==-1){  dis[V]=dis[u]+1,Q[++r]=V;  if (V==T) return 1;}    }    return 0;  }  int cur[N];  inline int dfs(int u,int flow){    if (u==T) return flow;    int used=0,now;    for (int p=cur[u];p;p=G[p].next){      cur[u]=p;      if (G[p].f && dis[V]==dis[u]+1){now=dfs(V,min(G[p].f,flow-used));G[p].f-=now; G[p^1].f+=now;used+=now; if (flow==used) break;      }    }    if (!used) dis[u]=-1;    return used;  }  inline int Dinic(){    int ret=0;    while (bfs()) memcpy(cur,head,sizeof(head)),ret+=dfs(S,1<<30);    return ret;  }}int n,m,a,b,mid;#define P(x,y) ((x)*2-(1-(y)))int lst[1005],pnt,pos;int vst[1005];int ans[1005],tot;inline void find(int u){  using namespace DINIC;  lst[++pnt]=u; vst[u]=1; if (u==T) pos=pnt;   for (int p=head[u];p;p=G[p].next)    if ((~p&1) && G[p^1].f && !vst[V])      find(V);}int main(){  int Q,iu,iv; using namespace DINIC;  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  read(Q);  while (Q--){    read(n); read(m); read(a); read(b); read(mid);    for (int i=1;i<=n;i++) link(P(i,0),P(i,1),1);    for (int i=1;i<=m;i++){      read(iu); read(iv);      link(P(iu,1),P(iv,0),1<<30);      link(P(iv,1),P(iu,0),1<<30);    }    S=2*n+1;    T=2*n+2;    link(S,P(mid,0),2); link(P(a,1),T,1); link(P(b,1),T,1);    link(P(mid,0),P(mid,1),1);    Dinic();     pnt=0; cl(vst); find(S);    tot=0;    for (int i=pos-2;i;i-=2) ans[++tot]=(lst[i]+1)>>1;    for (int i=pos+1;i<=pnt;i+=2) ans[++tot]=(lst[i]+1)>>1;    if (ans[1]==b) reverse(ans+1,ans+tot+1);    for (int i=1;i<=tot;i++)      printf("%d ",ans[i]);    printf("\n");    clear();  }  return 0;}


0 0
原创粉丝点击