[差分 上下界最大流] SRM 694 div1 SRMDiv0Easy

考虑差分下 那么区间 [l,r] 加就会让 l r+1减 那么就两点间连边
因为所有数相等 那么 ai,i>1 都等于0 这就是流量平衡
那么S向n+1点连边 1向T点连边 跑下界最大流就好了 答案就是流量

// BEGIN CUT HERE  
#include<conio.h>
#include<sstream>
// END CUT HERE  
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<string>
#include<set>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;

const int N=305;
const int M=5005;

struct edge{
  int u,v,f,next;
}G[M];
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);
}
#define V G[p].v

int tot;
int S,T;
int dis[N],Q[N],l,r;

inline bool bfs(){
  l=r=-1; for (int i=1;i<=tot;i++) dis[i]=-1;
  dis[S]=0; 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;
  for (int p=cur[u];p;p=G[p].next){
    cur[u]=p;
    if (dis[V]==dis[u]+1 && G[p].f){
      int d=dfs(V,min(flow-used,G[p].f));
      G[p].f-=d; G[p^1].f+=d;
      used+=d; if (used==flow) break;
    }
  }
  if (!used) dis[u]=-1;
  return used;
}
inline int Dinic(){
  int ret=0;
  while (bfs()){
    for (int i=1;i<=tot;i++) cur[i]=head[i];
    ret+=dfs(S,1<<30);
  }
  return ret;
}

int n,q,s,t;

class SRMDiv0Easy{
public:
  int get(int _N, vector <int> L, vector <int> R, vector <int> X, vector <int> Y){
    n=_N,s=n+2,t=n+3,S=n+4,T=n+5;
    tot=T; for (int i=1;i<=tot;i++) head[i]=0; inum=1;
    q=L.size(); int tmp=0;
    for (int i=0;i<q;i++){
      int l=L[i]+1,r=R[i]+1,x=X[i],y=Y[i];
      link(r+1,l,y-x); tmp+=x;
      link(S,l,x); link(r+1,T,x);
    }
    link(s,n+1,1<<30); link(1,t,1<<30);
    int heads=head[s],headt=head[t];
    link(t,s,1<<30);
    if (Dinic()!=tmp)
      return -1;
    int ans=G[inum].f;
    S=s; T=t; inum-=2; head[s]=heads; head[t]=headt;
    ans+=Dinic();
    return ans;
  }


  // 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(); }
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 Arg0 = 2; int Arr1[] = {0,1}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0,1}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,2}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {2,3}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arg5 = 2; verify_case(0, Arg5, get(Arg0, Arg1, Arg2, Arg3, Arg4)); }
  void test_case_1() { int Arg0 = 2; int Arr1[] = {0,1}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {0,1}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,3}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {2,4}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arg5 = -1; verify_case(1, Arg5, get(Arg0, Arg1, Arg2, Arg3, Arg4)); }
  void test_case_2() { int Arg0 = 3; int Arr1[] = {0,1,0,0,2}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {2,2,1,0,2}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,3,1,4,2}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {11,13,19,15,17}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arg5 = 41; verify_case(2, Arg5, get(Arg0, Arg1, Arg2, Arg3, Arg4)); }
  void test_case_3() { int Arg0 = 12; int Arr1[] = {0,0,1,4,9,7,0}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {6,11,11,4,10,11,0}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,73,334,1,1,5,362}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {546,342,645,249,999,535,458}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arg5 = -1; verify_case(3, Arg5, get(Arg0, Arg1, Arg2, Arg3, Arg4)); }
  void test_case_4() { int Arg0 = 200; int Arr1[] = {0,49,0,97,0,65,0,55,0,24,0,86,0,139,0,34,0,11,0,62,0,172,0,59,0,97,0,47,0,156,0,24,0,103,0,184,0,130,0,154,0,26,0,121,0,72,0,183,0,5}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {48,199,96,199,64,199,54,199,23,199,85,199,138,199,33,199,10,199,61,199,171,199,58,199,96,199,46,199,155,199,23,199,102,199,183,199,129,199,153,199,25,199,120,199,71,199,182,199,4,199}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {1,1,1,1,2,1,2,2,2,2,1,1,1,1,2,1,1,1,1,1,2,2,2,1,2,1,1,2,2,1,1,1,2,2,1,1,2,1,1,1,1,1,2,2,2,2,2,2,2,1}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {964,962,952,993,983,973,971,954,978,980,958,999,991,978,977,991,971,976,977,998,968,992,951,955,987,981,986,958,968,966,992,957,975,995,958,995,983,985,956,974,966,986,985,999,959,989,980,998,971,973}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arg5 = 24202; verify_case(4, Arg5, get(Arg0, Arg1, Arg2, Arg3, Arg4)); }
  void test_case_5() { int Arg0 = 5; int Arr1[] = {}; vector <int> Arg1(Arr1, Arr1 + (sizeof(Arr1) / sizeof(Arr1[0]))); int Arr2[] = {}; vector <int> Arg2(Arr2, Arr2 + (sizeof(Arr2) / sizeof(Arr2[0]))); int Arr3[] = {}; vector <int> Arg3(Arr3, Arr3 + (sizeof(Arr3) / sizeof(Arr3[0]))); int Arr4[] = {}; vector <int> Arg4(Arr4, Arr4 + (sizeof(Arr4) / sizeof(Arr4[0]))); int Arg5 = 0; verify_case(5, Arg5, get(Arg0, Arg1, Arg2, Arg3, Arg4)); }

  // END CUT HERE

};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值