【NOI赛前训练】——专项测试1·网络流

T1:

题目大意:

  传送门

  给一个长度为$n(n<=200)$的数列$h$,再给$m$个可以无限使用的操作,第$i$个操作为给长度为花费$c_i$的价值给长度为$l_i$的数列子序列+1或-1,求将数列变为不下降数列的最小花费。

题解:

第一部分(上下界最小费用可行流):  

  设$h_0=-inf,h_{n+1}=inf$,令$a$为$h$的差分数组,即$a_i=h_{i}-h_{i-1}$。考虑当对于区间$[l,r]$操作时(比如+1),相当于$a_{r+1}$减少1,$a_{l}$增加1。若将$a$数组看做点集,这个变化相当于从$r+1$到$l$的一条流量为$1$的有向边,反之(-1)亦然。

  显然问题相当于把$a$数组元素均变为 不为0。那么我们由S向$a_{i}>0$的位置连$flow=[0,a_{i}],cost=0$的边,表示${i}$可以减少流量上下界,对于$a_{i}<0$的位置,我们至少要使其增加$-a_i$所以我们向$T$连$flow=[-a_i,inf],cost=0$的边。对于每个操作我们由于可无限使用我们就给所有合法位置连$flow=[0,inf],cost=c_{i}$的边,然后我们可以跑一个上下界解决问题。

  等等,这样的确解决了问题,不过我们观察一下这个图,会发现上下界源点只连向了$T$,而上下界汇点只被那些$a_{i}<0$的点连接到。

  我们把这个图转化一下,会发现对于上面的建图方式,我们只把$a_{i}<0$的边建成$flow=-a_i,cost=0$的边即可,根本不需要跑上下界。这就是另外一种思考方式。

第二部分(最小费用最大流):

  我们考虑那些$a_{i}<0$的点变为$0$一定比使其变为任一整数更优秀,同时这也是我们的判断有没有解的依据。

  所以我们就直接由$a_{i}<0$的点连向$T$的边为$flow=-a_i,cost=0$即可,如果所有连向$T$的边都流满,说明有解,同时由于上述性质,一定是最优解。

  

  不过这两个时间复杂度并没有太大区别。

代码:

  1 #include "bits/stdc++.h"
  2
  3 using namespace std;
  4
  5 #define inf 0x3f3f3f3f
  6
  7 inline int read() {
  8     int s=0,k=1;char ch=getchar ();
  9     while (ch<‘0‘|ch>‘9‘) ch==‘-‘?k=-1:0,ch=getchar();
 10     while (ch>47&ch<=‘9‘) s=s*10+(ch^48),ch=getchar();
 11     return s*k;
 12 }
 13
 14 const int N=1e3+10;
 15
 16 struct edges {
 17     int v,cap,cost;edges *pair,*last;
 18 }edge[N*N],*head[N];int cnt;
 19
 20 inline void push(int u,int v,int cap,int cost) {
 21     edge[++cnt]=(edges){v,cap,cost,edge+cnt+1,head[u]},head[u]=edge+cnt;
 22     edge[++cnt]=(edges){u,0,-cost,edge+cnt-1,head[v]},head[v]=edge+cnt;
 23 }
 24
 25 int S,T,ss,tt,n,fl,m;
 26 int piS,vis[N];
 27 long long cost;
 28
 29 inline int aug(int x,int w) {
 30     if (x==T) return cost+=1ll*piS*w,fl+=w,w;
 31     vis[x]=true;
 32     int ret=0;
 33     for (edges *i=head[x];i;i=i->last)
 34         if (i->cap&&!i->cost&&!vis[i->v])   {
 35             int flow=aug(i->v,min(i->cap,w));
 36             i->cap-=flow,i->pair->cap+=flow,ret+=flow,w-=flow;
 37             if (!w) break;
 38         }
 39     return ret;
 40 }
 41
 42 inline bool modlabel() {
 43     static int d[N];
 44     memset(d,0x3f,sizeof d);d[T]=0;
 45     static deque<int> q;q.push_back(T);
 46     int dt;
 47     while (!q.empty()) {
 48         int x=q.front();q.pop_front();
 49         for (edges *i=head[x];i;i=i->last)
 50             if (i->pair->cap&&(dt=d[x]-i->cost)<d[i->v])
 51                 (d[i->v]=dt)<=d[q.size()?q.front():0]
 52                     ?q.push_front(i->v):q.push_back(i->v);
 53     }
 54     for (int i=S;i<=T;++i)
 55         for (edges *j=head[i];j;j=j->last)
 56             j->cost+=d[j->v]-d[i];
 57     piS+=d[S];
 58     return d[S]<inf;
 59 }
 60
 61 inline void solve() {
 62     piS = cost = 0;
 63     while(modlabel())
 64         do memset(vis,0,sizeof vis);
 65     while(aug(S, inf));
 66 }
 67
 68 int h[N],a[N],c[N],l[N],typ[N];
 69 int f[N],g[N];
 70
 71 int main(){
 72     n=read(),m=read();
 73     for (int i=1;i<=n;++i)
 74         h[i]=read();
 75     for (int i=n;i>1;--i)
 76         h[i]=h[i]-h[i-1];
 77     h[1]=inf,h[n+1]=inf;
 78     ss=n+2,tt=ss+1,T=tt+1;
 79     char opt[2];
 80     for (int i=1;i<=m;++i) {
 81         scanf("%s",opt),l[i]=read(),c[i]=read();
 82         typ[i]=opt[0]==‘+‘;
 83     }
 84     ++n;
 85     for (int i=1;i<=n;++i)
 86         if (h[i] > 0)
 87             push(ss,i,h[i],0);
 88         else if(h[i]<0)  push(i,tt,inf,0),a[i]=-h[i],a[tt]+=h[i],push(i,T,a[i],0);
 89     push(tt,ss,inf,0);
 90     push(S,tt,-a[tt],0);
 91     memset(f,0x3f,sizeof(f));
 92     f[0]=0;
 93     memcpy(g,f,sizeof g);
 94     for (int j=1;j<=m;++j)
 95         for (int k=l[j];k<=n;k+=l[j])
 96             if(typ[j])
 97                 for (int i=n-1;i>=l[j];--i)
 98                     f[i]=min(f[i],f[i-l[j]]+c[j]);
 99             else
100                 for (int i=n-1;i>=l[j];--i)
101                     g[i]=min(g[i],g[i-l[j]]+c[j]);
102     // puts()
103     for (int j=1;j<=m;++j)
104         if (typ[j]){
105             if (f[l[j]]==c[j])
106                 for (int i=l[j]+1;i<=n;++i)
107                     push(i,i-l[j],inf,c[j]);
108         }else
109             if (g[l[j]]==c[j])
110                 for (int i=1;i+l[j]<=n;++i)
111                     push(i,i+l[j],inf,c[j]);
112     solve();
113     if (fl==-a[tt])
114         printf("%lld\n",cost);
115     else puts("-1");
116 }

上下界

  1 #include "bits/stdc++.h"
  2
  3 using namespace std;
  4
  5 #define inf 0x3f3f3f3f
  6
  7 inline int read() {
  8     int s=0,k=1;char ch=getchar ();
  9     while (ch<‘0‘|ch>‘9‘) ch==‘-‘?k=-1:0,ch=getchar();
 10     while (ch>47&ch<=‘9‘) s=s*10+(ch^48),ch=getchar();
 11     return s*k;
 12 }
 13
 14 const int N=1e3+10;
 15
 16 struct edges {
 17     int v,cap,cost;edges *pair,*last;
 18 }edge[N*N],*head[N];int cnt;
 19
 20 inline void push(int u,int v,int cap,int cost) {
 21     edge[++cnt]=(edges){v,cap,cost,edge+cnt+1,head[u]},head[u]=edge+cnt;
 22     edge[++cnt]=(edges){u,0,-cost,edge+cnt-1,head[v]},head[v]=edge+cnt;
 23 }
 24
 25 int S,T,ss,tt,n,fl,m;
 26 int piS,vis[N];
 27 long long cost;
 28
 29 inline int aug(int x,int w) {
 30     if (x==T) return cost+=1ll*piS*w,fl+=w,w;
 31     vis[x]=true;
 32     int ret=0;
 33     for (edges *i=head[x];i;i=i->last)
 34         if (i->cap&&!i->cost&&!vis[i->v])   {
 35             int flow=aug(i->v,min(i->cap,w));
 36             i->cap-=flow,i->pair->cap+=flow,ret+=flow,w-=flow;
 37             if (!w) break;
 38         }
 39     return ret;
 40 }
 41
 42 inline bool modlabel() {
 43     static int d[N];
 44     memset(d,0x3f,sizeof d);d[T]=0;
 45     static deque<int> q;q.push_back(T);
 46     int dt;
 47     while (!q.empty()) {
 48         int x=q.front();q.pop_front();
 49         for (edges *i=head[x];i;i=i->last)
 50             if (i->pair->cap&&(dt=d[x]-i->cost)<d[i->v])
 51                 (d[i->v]=dt)<=d[q.size()?q.front():0]
 52                     ?q.push_front(i->v):q.push_back(i->v);
 53     }
 54     for (int i=S;i<=T;++i)
 55         for (edges *j=head[i];j;j=j->last)
 56             j->cost+=d[j->v]-d[i];
 57     piS+=d[S];
 58     return d[S]<inf;
 59 }
 60
 61 inline void solve() {
 62     piS = cost = 0;
 63     while(modlabel())
 64         do memset(vis,0,sizeof vis);
 65     while(aug(S, inf));
 66 }
 67
 68 int h[N],a[N],c[N],l[N],typ[N];
 69 int f[N],g[N];
 70
 71 int main(){
 72     n=read(),m=read();
 73     for (int i=1;i<=n;++i)
 74         h[i]=read();
 75     for (int i=n;i>1;--i)
 76         h[i]=h[i]-h[i-1];
 77     h[1]=inf,h[n+1]=inf;
 78     // ss=n+2,tt=ss+1,T=tt+1;
 79     char opt[2];
 80     for (int i=1;i<=m;++i) {
 81         scanf("%s",opt),l[i]=read(),c[i]=read();
 82         typ[i]=opt[0]==‘+‘;
 83     }
 84     ++n;T=n+1;
 85     for (int i=1;i<=n;++i)
 86         if (h[i] > 0)
 87             push(S,i,h[i],0);
 88         else if(h[i]<0)  push(i,T,-h[i],0),a[tt]+=h[i];//,push(i,T,a[i],0);
 89     // push(tt,ss,inf,0);
 90     // push(S,tt,-a[tt],0);
 91     memset(f,0x3f,sizeof(f));
 92     f[0]=0;
 93     memcpy(g,f,sizeof g);
 94     for (int j=1;j<=m;++j)
 95         for (int k=l[j];k<=n;k+=l[j])
 96             if(typ[j])
 97                 for (int i=n-1;i>=l[j];--i)
 98                     f[i]=min(f[i],f[i-l[j]]+c[j]);
 99             else
100                 for (int i=n-1;i>=l[j];--i)
101                     g[i]=min(g[i],g[i-l[j]]+c[j]);
102     for (int j=1;j<=m;++j)
103         if (typ[j]){
104             if (f[l[j]]==c[j])
105                 for (int i=l[j]+1;i<=n;++i)
106                     push(i,i-l[j],inf,c[j]);
107         }else
108             if (g[l[j]]==c[j])
109                 for (int i=1;i+l[j]<=n;++i)
110                     push(i,i+l[j],inf,c[j]);
111     solve();
112     // printf("%d %d\n",fl);
113     if (fl==-a[tt])
114         printf("%lld\n",cost);
115     else puts("-1");
116 }

最大流

T2:

题目大意:

  emmm,由于并没在网上找到这题,题意我就不发了,仅供自己记忆233。

题解:

  这是一道及其简单的模拟网络流最小割的静态仙人掌。(完全不需要题意……各位就知道了

  没什么好说的……

  tajan缩点,树剖+线段树维护,以及8k代码。没了。

代码:

  1 #include "bits/stdc++.h"
  2
  3 inline int read(){
  4     int s=0,k=1;char ch=getchar();
  5     while (ch<‘0‘|ch>‘9‘) ch==‘-‘?k=-1:0,ch=getchar();
  6     while (ch>47&ch<=‘9‘) s=s*10+(ch^48),ch=getchar();
  7     return s*k;
  8 }
  9
 10 using namespace std;
 11
 12 #define inf 0x7fffffff
 13
 14 const int N=5e5+10,M=1e6+10;
 15
 16 struct node {
 17     int a,b,w,id;
 18 }line[N];
 19
 20 struct edges{
 21     int v,w;edges *last;node *id;
 22 }edge[N<<1],*head[N];int cnt=1;
 23
 24 inline void push(int u,int v,int w){
 25     edge[++cnt]=(edges) {v,w,head[u]},head[u]=edge+cnt;
 26 }
 27
 28 int bccno[N],bcc_cnt,low[N],dfn[N],idx,stk[N],top,size[N],aa[N];
 29 bool vis[N],used[N];
 30
 31 inline void tarjan(int x,int fa) {
 32     low[x]=dfn[x]=++idx;
 33     stk[++top]=x;
 34     for (edges *i=head[x];i;i=i->last)  if(i->v!=fa) {
 35         if(!dfn[i->v])
 36             tarjan(i->v,x),
 37             low[x]=min(low[x],low[i->v]);
 38         else    low[x]=min(low[x],dfn[i->v]);
 39     }
 40     if(dfn[fa]<low[x]) {
 41         bcc_cnt++;int t;
 42         do t=stk[top--],bccno[t]=bcc_cnt,++size[bcc_cnt];while (t!=x);
 43     }
 44 }
 45
 46 struct Tree {
 47     int val;
 48     Tree *lc,*rc;
 49     inline void update() {
 50         val=min(lc->val,rc->val);
 51     }
 52 }tree[N<<3];int cnt_tree;
 53
 54 struct Segment{
 55     Tree *root;
 56
 57     inline void build(Tree *&u,int l,int r) {
 58         if(!u) u=tree+cnt_tree,cnt_tree++;
 59         if(l==r)  return void(u->val=aa[l]);
 60         int mid=l+r>>1;
 61         build(u->lc,l,mid);
 62         build(u->rc,mid+1,r);
 63         u->update();
 64     }
 65
 66     inline void change(Tree *u,int l,int r,int x,int val){
 67         if(l==r) return void(u->val=val);
 68         int mid=l+r>>1;
 69         if (x>mid) change(u->rc,mid+1,r,x,val);
 70         else change(u->lc,l,mid,x,val);
 71         u->update();
 72     }
 73
 74     inline int query(Tree *u,int l,int r,int x,int y) {
 75         if (x>y) return inf;
 76         if(x<=l&&r<=y) return u->val;
 77         int mid=l+r>>1,ret=0x7fffffff;
 78         if (y>mid) ret=query(u->rc,mid+1,r,x,y);
 79         if(x<=mid) ret=min(ret,query(u->lc,l,mid,x,y));
 80         return ret;
 81     }
 82 }seg[N],rt,sft;
 83
 84 int n,m,pos[N];
 85 vector<int> bcc[N],val[N];
 86
 87 inline void dfs(int x) {
 88     vis[x]=true;
 89     bcc[bccno[x]].push_back(x);
 90     pos[x]=bcc[bccno[x]].size();
 91     for (edges *i=head[x];i;i=i->last)  {
 92         if (!vis[i->v]&&bccno[x]==bccno[i->v]){
 93         i->id->id=pos[x],val[bccno[x]].push_back(i->w),used[i-edge]=used[(i-edge)^1]=true;
 94         dfs(i->v);
 95     }
 96     }
 97     if(pos[x]==size[bccno[x]])
 98         for (edges *i=head[x];i;i=i->last)  if (!used[i-edge]&&bcc[bccno[x]][0]==i->v)
 99             i->id->id=pos[x],val[bccno[x]].push_back(i->w);
100 }
101
102 int heavy[N],sz[N],fat[N],gra[N],deep[N],tid[N],rid[N],up[N],down[N],upb[N];
103
104 inline void dfs(int x,int fa){
105     sz[x]=1;
106     for (edges *i=head[x];i;i=i->last)   if(i->v!=fa){
107         deep[i->v]=deep[x]+1,dfs(i->v,x);
108         sz[x]+=sz[i->v];
109         if (sz[heavy[x]]<sz[i->v])
110             heavy[x]=i->v;
111     }
112     fat[x]=fa;
113 }
114
115 inline void dfs(int x,int fa,int gr) {
116     gra[x]=gr;
117     tid[x]=++tid[0];
118     rid[tid[0]]=x;
119
120     if (heavy[x]) {
121         dfs(heavy[x],x,gr);
122         for (edges *i=head[x];i;i=i->last)  if (i->v!=fa&&i->v!=heavy[x])
123             dfs(i->v,x,i->v);
124         for (edges *i=head[x];i;i=i->last)  if (i->v!=fa)
125             aa[tid[i->v]]=i->w;
126     }
127 }
128
129 inline int query(int x,int l,int r){
130     if (l==r) return inf;
131     if (l>r) swap(l,r);
132     return     seg[x].query(seg[x].root,1,size[x],l,r-1)+
133            min(seg[x].query(seg[x].root,1,size[x],r,n),
134                seg[x].query(seg[x].root,1,size[x],1,l-1)) ;
135 }
136
137 inline void sdfs(int x) {
138     for (edges *i=head[x];i;i=i->last) if(i->v!=fat[x]){
139         up[i->v]=deep[bccno[i->id->a]]>deep[bccno[i->id->b]]?i->id->a:i->id->b;
140         upb[i->v]=i->id->a^i->id->b^up[i->v];
141         sdfs(i->v);
142         if (i->v==heavy[x])
143             down[x]=deep[bccno[i->id->a]]<deep[bccno[i->id->b]]?i->id->a:i->id->b;
144         if (i->v==heavy[x]&&fat[x])     {
145             int l=pos[up[x]],r=pos[down[x]];
146             aa[tid[x]]=query(x,l,r);
147         }
148     }
149 }
150
151 inline void change(int id,int f) {
152     int a=line[id].a,b=line[id].b;
153     if (bccno[a]^bccno[b])    {
154         a=bccno[a],b=bccno[b];
155         if (deep[a]<deep[b]) swap(a,b);
156         rt.change(rt.root,1,bcc_cnt,tid[a],f);
157     }else {
158         b=bccno[a];
159         seg[b].change(seg[b].root,1,size[b],line[id].id,f);
160         if (up[b]&&down[b]) {
161             int l=pos[up[b]],r=pos[down[b]],val=query(b,l,r);
162             sft.change(sft.root,1,bcc_cnt,tid[b],val);
163         }
164     }
165 }
166
167 inline int query (int x,int y){
168     int ret=inf;
169     if (bccno[x]==bccno[y]) {
170         int l=pos[x],r=pos[y];
171         return query(bccno[x],l,r);
172     }
173     int a=x,b=y;
174     x=bccno[x],y=bccno[y];
175     while (gra[x]!=gra[y]) {
176         if (deep[gra[x]]<deep[gra[y]]) swap(x,y),swap(a,b);
177         ret=min(ret,rt.query(rt.root,1,bcc_cnt,tid[gra[x]],tid[x]));
178         int l,r;
179         l=pos[a],r=pos[up[x]];
180         ret=min(ret,query(x,l,r));
181         a=upb[gra[x]];
182         if (gra[fat[x]]==gra[x])    {
183             x=fat[x];
184             ret=min(ret,sft.query(sft.root,1,bcc_cnt,tid[gra[x]],tid[x]));
185         }
186         x=fat[gra[x]];
187     }
188     if (deep[x]>deep[y]) swap(x,y),swap(a,b);
189     if (x^y) {
190         ret=min(ret,rt.query(rt.root,1,bcc_cnt,tid[x]+1,tid[y]));
191         int l=pos[b],r=pos[up[y]];
192         ret=min(ret,query(y,l,r));
193         ret=min(ret,sft.query(sft.root,1,bcc_cnt,tid[x]+1,tid[y]-1));
194         l=pos[a],r=pos[down[x]];
195         ret=min(ret,query(x,l,r));
196     }else
197         ret=min(ret,query(x,pos[a],pos[b]));
198     return ret;
199 }
200
201 int main(){
202     n=read(),m=read();
203     for (int i=1;i<=m;++i) {
204         int a=read(),b=read(),w=read();
205         line[i]=(node){a,b,w};
206         push(a,b,w),push(b,a,w);
207         edge[cnt].id=edge[cnt-1].id=line+i;
208     }
209     tarjan(1,0);
210     for (int i=1;i<=n;++i)
211         if(!vis[i]) dfs(i);
212
213     for (int i=1;i<=bcc_cnt;++i)    {
214         if (size[i]==1) val[i].push_back(inf);
215         for (int j=1;j<=size[i];++j)
216             aa[j]=val[i][j-1];
217         seg[i].build(seg[i].root,1,size[i]);
218     }
219     memset(head,0,sizeof(head));
220     cnt=0;
221     for (int i=1;i<=m;++i)  {
222         int a,b,w=line[i].w;
223         if ((a=bccno[line[i].a])!=(b=bccno[line[i].b]))
224             push(a,b,w),push(b,a,w),edge[cnt].id=edge[cnt-1].id=line+i;
225     }
226     dfs(1,0);
227     dfs(1,0,1);
228     aa[1]=0;
229     rt.build(rt.root,1,bcc_cnt);
230     memset(aa,127,sizeof aa);
231
232     int Q=read(),typ,a,b;
233     sdfs(1);
234     sft.build(sft.root,1,bcc_cnt);
235     while (Q--) {
236         typ=read(),a=read(),b=read();
237         if (typ)  change(a,b);
238         else   printf("%d\n",query(a,b));
239     }
240 }

生平第一棵仙人掌

T3

题目大意:

  传送门

  $n*n$的棋盘,有一些位置可以放棋子,有一些已经放了棋子,有一些什么都没有,也不能放,要求放置以后满足:第i行和第i列的棋子数相同,同时每行的棋子数占总数比例小于$\frac{A}{B}$。求最多可以放多少,无解则输出$impossible$。

题解:

   Orz一发大佬——传送门

  先把整张图放满,题目就转化为最少删多少点就合法。

  我们用$numx$来记录每行可以放的和已经放棋子总数,$numy$记录每列。从$S$向第i行连流量为$numx_i$的0费用边,从第j列向$T$连流量为$numy_j$的边。先不考虑怎么构建中间的图,在不考虑$\frac{A}{B}$的情况,我们需要判断流量合法的,我们可以让到$T$的边都满流意味着选了和没选的可以构成全集。

  我们对于可以放棋子的地方$(x,y)$,由第$x$行到第$y$列连$flow=1,cost=1$的边,表示将这个点删去的所需价值。

  考虑后一个限制。

  我们可以枚举每一行最多放置的棋子个数$f$,然后我们从第$i$行向第$i$列连一条$flow=f,cost=0$的边。表示第i行选了最多保留$f$个棋子,第$i$列保留棋子等同于这条边的流量,因为其他连向第$i$列的边都是要费用的,对第$i$行来讲其他的出边也是要费用的,而那些要费用的边就是删去的集合。

  然后判断一下当前解是否合法即可。

代码:

  1 #include "bits/stdc++.h"
  2
  3 using namespace std;
  4
  5 #define inf 0x3f3f3f3f
  6
  7 inline int read() {
  8     int s=0,k=1;char ch=getchar ();
  9     while (ch<‘0‘|ch>‘9‘) ch==‘-‘?k=-1:0,ch=getchar();
 10     while (ch>47&ch<=‘9‘) s=s*10+(ch^48),ch=getchar();
 11     return s*k;
 12 }
 13
 14 const int N=100;
 15
 16 struct edges {
 17     int v,cap,cost;edges *pair,*last;
 18 }edge[N*N],*head[N];int cnt;
 19
 20 inline void push(int u,int v,int cap,int cost) {
 21     edge[++cnt]=(edges){v,cap,cost,edge+cnt+1,head[u]},head[u]=edge+cnt;
 22     edge[++cnt]=(edges){u,0,-cost,edge+cnt-1,head[v]},head[v]=edge+cnt;
 23 }
 24
 25 int S,T,n,fl,ans;
 26 int piS,vis[N];
 27 int cost;
 28
 29 inline int aug(int x,int w) {
 30     if (x==T) return cost+=1ll*piS*w,fl+=w,w;
 31     vis[x]=true;
 32     int ret=0;
 33     for (edges *i=head[x];i;i=i->last)
 34         if (i->cap&&!i->cost&&!vis[i->v])   {
 35             int flow=aug(i->v,min(i->cap,w));
 36             i->cap-=flow,i->pair->cap+=flow,ret+=flow,w-=flow;
 37             if (!w) break;
 38         }
 39     return ret;
 40 }
 41
 42 inline bool modlabel() {
 43     static int d[N];
 44     memset(d,0x3f,sizeof d);d[T]=0;
 45     static deque<int> q;q.push_back(T);
 46     int dt;
 47     while (!q.empty()) {
 48         int x=q.front();q.pop_front();
 49         for (edges *i=head[x];i;i=i->last)
 50             if (i->pair->cap&&(dt=d[x]-i->cost)<d[i->v])
 51                 (d[i->v]=dt)<=d[q.size()?q.front():0]
 52                     ?q.push_front(i->v):q.push_back(i->v);
 53     }
 54     for (int i=S;i<=T;++i)
 55         for (edges *j=head[i];j;j=j->last)
 56             j->cost+=d[j->v]-d[i];
 57     piS+=d[S];
 58     return d[S]<inf;
 59 }
 60
 61 inline void solve() {
 62     piS = cost = 0;
 63     while(modlabel())
 64         do memset(vis,0,sizeof vis);
 65     while(aug(S, inf));
 66 }
 67
 68 char mp[N][N];
 69 int numx[N],numy[N],A,B;
 70
 71 int main() {
 72     n=read(),A=read(),B=read();
 73     T=n<<1|1;
 74     int used=0,sum=0;
 75     ans=-1;
 76     for (int i=1;i<=n;++i)  {
 77         scanf("%s",mp[i]+1);
 78         for (int j=1;j<=n;++j)
 79             if(mp[i][j]==‘C‘||mp[i][j]==‘.‘)    {
 80                 ++sum,++numx[i],++numy[j];
 81                 used+=mp[i][j]==‘C‘;
 82             }
 83     }
 84     for (int flow=0;flow<=n;++flow) {
 85         memset(head,0,sizeof head);
 86         cnt=0;fl=0;
 87         for (int i=1;i<=n;++i) {
 88             push(S,i,numx[i],0);
 89             push(i+n,T,numy[i],0);
 90             push(i,i+n,flow,0);
 91             for (int j=1;j<=n;++j)
 92                 if(mp[i][j]==‘.‘)
 93                     push(i,j+n,1,1);
 94         }
 95         solve();
 96         if (fl==sum&&flow*B<=(sum-cost)*A)
 97             ans=max(ans,sum-cost);
 98     }
 99     if (ans==-1)   puts("impossible");
100     else printf("%d\n",ans-used);
101 }

t3

原文地址:https://www.cnblogs.com/Troywar/p/8847666.html

时间: 2024-10-07 17:27:39

【NOI赛前训练】——专项测试1·网络流的相关文章

[NOI赛前训练]——专项测试3&#183;数学

由于并不想写T1和T2的题解……所有只有T3的题解了. T3 由于内部题就只写题解了. 好吧,我是一点都不想写…… 说一下这zz题解哪里写错了吧…… ……不想写…… 就说一个吧…… $n-\frac{k-i}{2}$应该是$\frac{k-i}{2}$. 好累啊,完全不想写题解,有空再说吧. 1 #include "bits/stdc++.h" 2 3 using namespace std; 4 5 const int N=4e2+10; 6 7 double f[N][N],p[N

Caffe上用SSD训练和测试自己的数据

    学习caffe第一天,用SSD上上手. 我的根目录$caffe_root为/home/gpu/ljy/caffe 一.运行SSD示例代码 1.到https://github.com/weiliu89/caffe.git下载caffe-ssd代码,是一个caffe文件夹 2.从已经配置好的caffe目录下拷贝一个Makefile.config放到$caffe_root下 3.在$caffe_root下打开命令行终端,输入以下命令 make -j8 make py make test -j8

不要怂,就是GAN (生成式对抗网络) (四):训练和测试 GAN

在 /home/your_name/TensorFlow/DCGAN/ 下新建文件 train.py,同时新建文件夹 logs 和文件夹 samples,前者用来保存训练过程中的日志和模型,后者用来保存训练过程中采样器的采样图片,在 train.py 中输入如下代码: # -*- coding: utf-8 -*- import tensorflow as tf import os from read_data import * from utils import * from ops impo

Ubuntu14.04+caffe+cuda7.5 环境搭建以及MNIST数据集的训练与测试

Ubuntu14.04+caffe+cuda 环境搭建以及MNIST数据集的训练与测试 一.ubuntu14.04的安装: ubuntu的安装是一件十分简单的事情,这里给出一个参考教程: http://jingyan.baidu.com/article/76a7e409bea83efc3b6e1507.html 二.cuda的安装: 1.首先下载nvidia cuda的仓库安装包(我的是ubuntu 14.04 64位,所以下载的是ubuntu14.04的安装包,如果你是32位的可以参看具体的地

【金阳光测试】KK公益讲座第63期-5月30号(周六晚八点) 分享主题: IOS专项测试基础

[金阳光测试]KK公益讲座第63期-5月30号(周六晚八点)分享主题: IOS专项测试基础听课地点:http://www.chuanke.com/1983382-110713.html主讲:小白老师老师简介:前风行网.腾讯测试,现为一流互联网公司任职高级开发测试时间:5月30号 晚上8点开始

使用CNN(convolutional neural nets)检测脸部关键点教程(二):浅层网络训练和测试

第三部分 第一个模型:一个隐层结构的传统神经网络 这一部分让我们从代码开始: # add to kfkd.py from lasagne import layers from lasagne.updates import nesterov_momentum from nolearn.lasagne import NeuralNet net1 = NeuralNet( layers=[ # three layers: one hidden layer ('input', layers.InputL

windows下的cafee训练和测试mnist数据集

一.mnist数据集 mnist是一个手写数字数据库,由Google实验室的Corinna Cortes和纽约大学柯朗研究院的Yann LeCun等人建立,它有60000个训练样本集和10000个测试样本集.mnist数据库官方网址为:http://yann.lecun.com/exdb/mnist/ .可直接下载四个解压文件,分别对应:训练集样本.训练集标签.测试集样本和测试集标签.解压缩之后发现,其是在一个文件中包含了所有图像. 二.caffe支持的数据格式:Lmdb和Leveldb 它们都

Android性能专项测试测试点指导(二)

Android性能专项测试测试点指导(一) 上一篇文章通过导图的方式介绍了性能专项的几个测试点,那么今天将会详细阐述下. 内存: 内存泄漏: 老生常谈的最多就是这货,这家伙的测试方法其实是最简单也是最难的,为什么简单,因为你要定位到路径,只需要重复操作即可,比如你怀疑播放器泄漏了,重复进入退出N次,那么就可以确定是播放器出问题了,可以提单了:说难,你需要进一步分析到底是哪里泄漏了,通过MAT工具去对比,去分析定位到类,那就需要精力和时间了,通常还吃力不讨好-最近,出现了这样一个工具LeakCan

Caffe 训练和测试自己的图片

  Caffe学习系列(12):训练和测试自己的图片  在caffe上跑自己的数据