今天又是猝不及防的一场考试。
我赶紧去打卡,于是get:参加模拟赛,爆零。
T1:
这不是秦神上次的原题吗?赶紧粘一发代码走了(不)。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 #define debug cout 8 using namespace std; 9 const int maxn=2e2+1e1,maxm=4e4+1e2,maxe=55; 10 const int inf=0x3f3f3f3f; 11 12 int k[maxn],sum[maxn],n,full,mip,ans; 13 int st,ed,len; 14 bool vis[maxn]; 15 16 struct Elevator { 17 int h,x,y; 18 friend bool operator < (const Elevator &a,const Elevator &b) { 19 if( a.h != b.h ) return a.h < b.h; 20 if( a.x != b.x ) return a.x < b.x; 21 return a.y < b.y; 22 } 23 friend bool operator == (const Elevator &a,const Elevator &b) { 24 return a.h == b.h && a.x == b.x && a.y == b.y; 25 } 26 }; 27 vector<Elevator> v; 28 29 namespace Flow { 30 int s[maxn],t[maxm<<1],nxt[maxm<<1],f[maxm<<1],dep[maxn],cnt=1; 31 32 inline void coredge(int from,int to,int flow) { 33 t[++cnt] = to , f[cnt] = flow , 34 nxt[cnt] = s[from] , s[from] = cnt; 35 } 36 inline void singledge(int from,int to,int flow) { 37 coredge(from,to,flow) , coredge(to,from,0); 38 } 39 inline bool bfs() { 40 memset(dep,-1,sizeof(dep)) , dep[st] = 0; 41 queue<int> q; q.push(st); 42 while( q.size() ) { 43 const int pos = q.front(); q.pop(); 44 for(int at=s[pos];at;at=nxt[at]) { 45 if( f[at] && !~dep[t[at]] ) dep[t[at]] = dep[pos] + 1 , q.push(t[at]); 46 } 47 } 48 return ~dep[ed]; 49 } 50 inline int dfs(int pos,int flow) { 51 if( pos == ed ) return flow; 52 int ret = 0 , now = 0; 53 for(int at=s[pos];at;at=nxt[at]) 54 if( f[at] && dep[t[at]] > dep[pos] ) { 55 now = dfs(t[at],min(flow,f[at])); 56 ret += now , flow -= now , 57 f[at] -= now , f[at^1] += now; 58 if( !flow ) return ret; 59 } 60 if( !ret ) dep[pos] = -1; 61 return ret; 62 } 63 inline int dinic() { 64 int ret = 0 , now = 0; 65 while( bfs() ) 66 while( ( now = dfs(st,inf) ) ) ret += now; 67 return ret; 68 } 69 inline void reset() { 70 memset(s,0,sizeof(s)) , cnt = 1; 71 } 72 } 73 74 inline int countbit(int x) { 75 #define lowbit(x) (x&-x) 76 int ret = 0; 77 while( x ) ++ret , x -= lowbit(x); 78 return ret; 79 } 80 inline int covdep(int dep,int pos) { 81 return sum[dep-1] + pos; 82 } 83 84 inline int rebuild(int sta) { 85 Flow::reset() , memset(vis,0,sizeof(vis)); 86 int ret = 0; 87 for(int i=0;i<k[mip];i++) if( ! ( sta & ( 1 << i ) ) ) vis[covdep(mip,i+1)] = 1; 88 for(int i=0;i<len;i++) { 89 const int h = v[i].h , th = h != n ? h + 1 : 1; 90 if( h == mip) { 91 if( ( 1 << ( v[i].x - 1 ) ) & sta ) vis[covdep(th,v[i].y)] = 1; 92 } 93 else if( th == mip ) { 94 if( ( 1 << ( v[i].y - 1 ) ) & sta ) vis[covdep(h,v[i].x)] = 1; 95 }else { 96 if( ( h > mip && ( ( h - mip ) & 1 ) ) || ( h < mip && ! ( ( mip - h ) & 1 ) ) ) 97 Flow::singledge(covdep(h,v[i].x),covdep(th,v[i].y),1); 98 else Flow::singledge(covdep(th,v[i].y),covdep(h,v[i].x),1); 99 } 100 } 101 for(int i=1;i<=n;i++) { 102 if( ( i > mip && ( ( i - mip ) & 1 ) ) || ( i < mip && !( ( mip - i ) & 1 ) ) ) { 103 for(int j=1;j<=k[i];j++) 104 if( !vis[covdep(i,j)] ) Flow::singledge(st,covdep(i,j),1); 105 } else if( i != mip ) { 106 for(int j=1;j<=k[i];j++) 107 if( !vis[covdep(i,j)] ) Flow::singledge(covdep(i,j),ed,1); 108 } 109 } 110 for(int i=1;i<=full;i++) ret += !vis[i]; 111 ret -= Flow::dinic(); 112 return ret; 113 } 114 inline void getansodd() { 115 int fs = ( 1 << k[mip] ); 116 for(int i=0;i<fs;i++) ans = max( ans , rebuild(i) ); 117 } 118 inline void getanseven() { 119 for(int i=0;i<len;i++) { 120 const int x = covdep(v[i].h,v[i].x); 121 const int y = covdep(v[i].h!=n?v[i].h+1:1,v[i].y); 122 if( v[i].h & 1 ) Flow::singledge(x,y,1); 123 else Flow::singledge(y,x,1); 124 } 125 for(int i=1;i<=n;i++) { 126 if( i & 1 ) { 127 for(int j=1;j<=k[i];j++) 128 Flow::singledge( st , covdep(i,j) , 1 ); 129 } else { 130 for(int j=1;j<=k[i];j++) 131 Flow::singledge( covdep(i,j) , ed , 1 ); 132 } 133 } 134 ans = full - Flow::dinic(); 135 } 136 137 inline void pre() { 138 sort(v.begin(),v.end()); 139 len = unique(v.begin(),v.end()) - v.begin(); 140 for(int i=1;i<=n;i++) sum[i] = sum[i-1] + k[i]; 141 full = sum[n] , st = full + 1 , ed = full + 2; 142 *k = inf; 143 for(int i=1;i<=n;i++) if( k[i] < k[mip] ) mip = i; 144 } 145 146 int main() { 147 static int h,x,y; 148 scanf("%d",&n); 149 int t = 0; 150 while( scanf("%d%d%d",&x,&y,&h) == 3 ) { 151 v.push_back((Elevator){h,x,y}); 152 k[h] = max( k[h] , x ) , k[h!=n?h+1:1] = max( k[h!=n?h+1:1] , y ); 153 ++t; 154 } 155 pre(); 156 if( n & 1 ) getansodd(); 157 else getanseven(); 158 printf("%d\n",ans); 159 return 0; 160 }