POJ2396 代码

 

Source Code

Problem: 2396 User: forsona
Memory: 4980K Time: 141MS
Language: C++ Result: Accepted

  • Source Code
    #include"iostream"
    #include"cstdio"
    #include"algorithm"
    #include"cstring"
    #define INF 999999999
    using namespace std; 
    int maxf[500][500],minf[500][500],f[500][500],so,to,d[500],next[500][500],should,e[500],h[500],current[500];
    int inf[500],ouf[500],xxf[500][500],nnf[500][500],n,m;
    struct qnode
    {
      int p;
      qnode *next;       
    }*q;
    void Add(int p,int q,int xf,int nf)
    {
      maxf[p][q]=xf;    
      minf[p][q]=nf; 
      inf[q]+=nf;
      ouf[p]+=nf;  
      next[p][d[p]++]=q;
      next[q][d[q]++]=p;
    }
    void Ins(int p)
    {
      qnode *t=new qnode;
      t->p=p;
      t->next=q->next;
      q->next=t;   
    }
    bool xnf(int p,int q,char opt[3],int t)
    {
              if (opt[0]=='=')
                {
                xxf[p][q]=min(xxf[p][q],t);
                nnf[p][q]=max(nnf[p][q],t);
                if (t<0)
                  return false;
                }
              else
                if (opt[0]=='<')
                  {
                  xxf[p][q]=min(xxf[p][q],t-1);
                  if (t<=0)
                    return false;
                  }
                else
                  nnf[p][q]=max(nnf[p][q],t+1);
      return true;
    }
    bool Inp(void)
    {
      int i,j,k,t,p,q;
      char opt[3];
      memset(f,0,sizeof(f));
      memset(minf,0,sizeof(minf));
      memset(maxf,0,sizeof(maxf));
      memset(inf,0,sizeof(inf));  
      memset(ouf,0,sizeof(ouf)); 
      memset(d,0,sizeof(d));
      memset(current,0,sizeof(current)); 
      scanf("%d%d",&n,&m);
      for(i=1;i<=n+m;i++)
        for(j=1;j<=n+m;j++)
          {
          xxf[i][j]=INF;  
          nnf[i][j]=0;
          }
      for(i=1;i<=n;i++) 
        {
        scanf("%d",&t);
        Add(n+m+1,i,t,t);  
        }
      for(i=1;i<=m;i++) 
        {
        scanf("%d",&t);  
        Add(i+n,n+m+2,t,t);
        }    
      scanf("%d",&k); 
      for(i=0;i<k;i++)
        {
        scanf("%d%d%s%d",&p,&q,opt,&t);
        q=q+n;    
        if(p==0) 
          if (q!=n)
            for(p=1;p<=n;p++)
              {
              if (!xnf(p,q,opt,t))
                return false;
              }
          else
            for(p=1;p<=n;p++) 
              for(q=n+1;q<=n+m;q++)
                {
                if (!xnf(p,q,opt,t))
                  return false;
                }
        else
          if (q==n)
            for(q=n+1;q<=n+m;q++)
              {
              if (!xnf(p,q,opt,t))
                return false;
              }
          else
            if (!xnf(p,q,opt,t))
              return false;
        } 
      for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
          Add(i,n+j,xxf[i][n+j],nnf[i][n+j]);
      return true;
    }
    bool Zh(void)
    {
      int i,sinf,souf;
      so=0;
      to=n+m+3;
      sinf=souf=0;
      should=0;
      for(i=1;i<=n+m+2;i++)
        {
          next[so][d[so]++]=i;
          next[i][d[i]++]=so;         
          maxf[so][i]=inf[i];
          sinf+=inf[i];
          next[to][d[to]++]=i;
          next[i][d[i]++]=to;         
          maxf[i][to]=ouf[i];
          souf+=ouf[i];
        }
        
      if (sinf==souf)
        should=sinf;
      else
        return false;
      for(i=1;i<=n+m+2;i++)
        for(int j=1;j<=n+m+2;j++)
          maxf[i][j]-=minf[i][j];
      next[n+m+1][d[n+m+1]++]=n+m+2;
      next[n+m+2][d[n+m+2]++]=n+m+1;
      maxf[m+n+1][m+n+2]=maxf[m+n+2][m+n+1]=INF;
      return true;    
    } 
    void Push(int p,int q)
    { 
      int delta=min(e[p],maxf[p][q]-f[p][q]);
      e[p]-=delta;
      e[q]+=delta;
      f[p][q]+=delta;
      f[q][p]-=delta;
    }
    void ReLabel(int p)
    {
      int q,i;
      h[p]=INF;
      for(i=0;i<d[p];i++)
        { 
        q=next[p][i];
        if (maxf[p][q]>f[p][q])
          h[p]=min(h[p],h[q]);     
        }
      ++h[p];  
      current[p]=0;
    }
    void Discharge(int p)
    {
      int q;
      while(e[p])
        {
        if (current[p]==d[p])
          ReLabel(p);
        q=next[p][current[p]];
        if (maxf[p][q]>f[p][q]&&h[q]==h[p]-1)
          Push(p,q);
        else
          current[p]++;                       
        }   
    }
    bool ReLabel_to_Front(void)
    {
      qnode *t,*qt;
      int p,oh,i;
      if (!Inp())
        return false;
      if (!Zh())
        return false;
      memset(e,0,sizeof(e));  
      q=new qnode;
      q->next=NULL;
      for(i=so+1;i<to;i++)
        {
        f[so][i]=maxf[so][i];                  
        f[i][so]=-maxf[so][i];
        e[so]-=maxf[so][i];
        e[i]+=maxf[so][i];    
        Ins(i);
        } 
      memset(h,0,sizeof(h));
      h[so]=2*to+1;
      t=q;   
      while(t->next)
        {
        p=t->next->p;
        oh=h[p]; 
        Discharge(p);
        if (h[p]>oh)
          {
          t->next=t->next->next;
          Ins(p);
          t=q;
          }      
        else
          t=t->next;       
        }
      if (e[to]==should)
        return true;
      else
        return false;    
    }
    void Cl(void)
    {
      if (!ReLabel_to_Front())
        {
        printf("IMPOSSIBLE/n/n");
        return;                      
        }
      for(int i=1;i<=n;i++)
        {
        for(int j=1;j<=m;j++) 
          printf("%d ",f[i][n+j]+minf[i][n+j]);
        printf("/n");  
        } 
      printf("/n");  
    }
    int main()
    {
      int test;
      scanf("%d",&test);
      while(test--)
        Cl();
      return 0;  
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值