[暴搜 & 网络流判定] Topcoder SRM549 DIV1 Hard. CosmicBlocks

n很小

可以暴搜所有情况

合法性用上下界网络流判断

// BEGIN CUT HERE  

// END CUT HERE  
#include <vector>  
#include <list>  
#include <map>  
#include <set>  
#include <deque>  
#include <stack>  
#include <bitset>  
#include <algorithm>  
#include <functional>  
#include <numeric>  
#include <utility>  
#include <sstream>  
#include <iostream>  
#include <iomanip>  
#include <cstdio>  
#include <cmath>  
#include <cstdlib>  
#include <ctime>  
#include <queue>
#include <assert.h>
#include <cstring>  

using namespace std;  

const int N=1010,inf=1<<29;

int n,a[N],h[N],hst;
vector<int> c[N];

int u[N*N],d[N*N],adj[N*N],ans[750],t;

namespace flow{
  int cnt,S,T,ss,tt,G[N],dis[N],cur[N];
  struct edge{
    int t,nx,f;
  }E[N<<1];

  inline void addedge(int x,int y,int f){
    E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt; E[cnt].f=f;
    E[++cnt].t=x; E[cnt].nx=G[y]; G[y]=cnt; E[cnt].f=0;
  }

  queue<int> Q;

  inline bool bfs(){
    while(!Q.empty()) Q.pop();
    for(int i=0;i<=tt;i++) dis[i]=-1;
    dis[ss]=0; Q.push(ss);
    while(!Q.empty()){
      int x=Q.front(); Q.pop();
      for(int i=G[x];i;i=E[i].nx)
    if(E[i].f && !~dis[E[i].t]){
      dis[E[i].t]=dis[x]+1;
      if(E[i].t==tt) return true;
      Q.push(E[i].t);
    }
    }
    return false;
  }

  int dfs(int x,int f){
    if(x==tt || !f) return f;
    int used=0,w;
    for(int &i=cur[x];i;i=E[i].nx)
      if(E[i].f && dis[E[i].t]==dis[x]+1){
    w=dfs(E[i].t,min(f-used,E[i].f));
    E[i].f-=w; E[i^1].f+=w;
    if((used+=w)==f) return f;
      }
    if(!used) dis[x]=-1;
    return used;
  }

  inline bool check(){
    S=0; T=n+n+1; ss=T+1; tt=ss+1; cnt=1;
    int nf=0;
    for(int i=0;i<=tt;i++) G[i]=0;
    for(int i=1;i<=n;i++){
      addedge(i,tt,a[i]);
      addedge(ss,i+n,a[i]);
      nf+=a[i];
    }
    for(int i=0;i<c[1].size();i++) addedge(S,c[1][i],inf);
    for(int i=1;i<=n;i++) addedge(i+n,T,inf);
    for(int i=1;i<=t;i++)
      if(adj[i]){
    addedge(ss,u[i],1); addedge(d[i]+n,tt,1); addedge(d[i]+n,u[i],inf);
    nf++;
      }
    addedge(T,S,inf);
    while(bfs()){
      for(int i=0;i<=tt;i++) cur[i]=G[i];
      nf-=dfs(ss,inf); 
    }
    return !nf;
  }
}

int cur,cv[N],lst[N],vis[N];

inline void calc(){
  for(int i=1;i<=n;i++) cv[i]=0;
  for(int i=1;i<=t;i++)
    if(adj[i]) cv[d[i]]|=1<<u[i];
  for(int i=1;i<=n;i++){
    int x=lst[i];
    if(cv[x]) return ;
    for(int j=1;j<=t;j++)
      if(adj[j] && u[j]==x) cv[d[j]]^=1<<x;
  }
  cur++;
}

void lfs(int x){
  if(x>n) return calc();
  for(int i=1;i<=n;i++)
    if(!vis[i]){
      vis[i]=1; lst[x]=i; lfs(x+1); vis[i]=0;
    }
}

void check(){
  if(!flow::check()) return ;
  cur=0; lfs(1); ans[cur]++;
}

void pfs(int x){
  if(x>t) return check();
  adj[x]=0; pfs(x+1);
  adj[x]=1; pfs(x+1);
}

inline void judge(){
  for(int i=1;i<=n;i++) c[i].clear();
  for(int i=1;i<=n;i++)
    c[h[i]].push_back(i);
  for(int i=2;i<=n;i++)
    if(c[i].size() && !c[i-1].size()) return ;
  t=0; hst=1;
  for(int H=2;H<=n;H++)
    if(c[H].size()){
      for(int i=0;i<c[H-1].size();i++)
    for(int j=0;j<c[H].size();j++){
      ++t; u[t]=c[H][j]; d[t]=c[H-1][i];
    }
      hst=H;
    }
  pfs(1);
}

void dfs(int x){
  if(x>n) return judge();
  for(int i=1;i<=n;i++){
    h[x]=i; dfs(x+1);
  }
}

class CosmicBlocks{  
public:  
  int getNumOrders(vector <int> blockTypes, int minWays, int maxWays) {  
    n=blockTypes.size();
    memset(ans,0,sizeof(ans));
    for(int i=0;i<n;i++) a[i+1]=blockTypes[i];
    dfs(1); int ret=0;
    for(int i=minWays;i<=maxWays;i++) ret+=ans[i];
    return ret;
  }  


  // BEGIN CUT HERE
public:
  void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); if ((Case == -1) || (Case == 5)) test_case_5(); if ((Case == -1) || (Case == 6)) test_case_6(); if ((Case == -1) || (Case == 7)) test_case_7(); }
private:
  template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
  void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
  void test_case_0() { int Arr0[] = {2,2,2}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 1; int Arg3 = 6; verify_case(0, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
  void test_case_1() { int Arr0[] = {1,1,1,1,1,1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 720; int Arg2 = 720; int Arg3 = 1; verify_case(1, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
  void test_case_2() { int Arr0[] = {2,2}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 2; int Arg3 = 3; verify_case(2, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
  void test_case_3() { int Arr0[] = {1,2}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 2; int Arg3 = 2; verify_case(3, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
  void test_case_4() { int Arr0[] = {1}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 1; int Arg3 = 1; verify_case(4, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
  void test_case_5() { int Arr0[] = {1,2,4,8}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 5; int Arg2 = 30; int Arg3 = 27; verify_case(5, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
  void test_case_6() { int Arr0[] = {1,2,3,4,5,6}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1; int Arg2 = 720; int Arg3 = 4445; verify_case(6, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }
  void test_case_7() { int Arr0[] = {7500,1000,7500,1000,7500}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 8; int Arg2 = 88; int Arg3 = 448; verify_case(7, Arg3, getNumOrders(Arg0, Arg1, Arg2)); }

  // END CUT HERE

};  

// BEGIN CUT HERE  
int main()  
{  
  CosmicBlocks ___test;  
  ___test.run_test(-1);  
  system("pause");  
}  
// END CUT HERE  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值