标签:class std register pop front 怎么 main div while
日常网络流.
在一个n*m的矩阵中,每个格子有一定的高度,当高度为0时该格子便不存在,现在这个矩阵中有若干只蜥蜴,每只蜥蜴可以跳到距离不大于d的格子,问有几只蜥蜴无法逃离.
一开始看到这道题迷了好久,知道是网络流但是不懂怎么建边,仔细分析了一波题解,发现思路其实很清晰.
首先,由于格子有权值,于是想到拆点,一只蜥蜴想逃离,路线如下:源点-->柱顶1-->柱底1-->......-->柱顶p-->柱底p-->汇点,这样便可在保证柱子权值的情况下,求出可以逃离的蜥蜴最大数量.
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #define R register #define next mlgvegetable #define debug puts("mlg") using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; inline ll read(); inline void write(ll x); inline void writesp(ll x); inline void writeln(ll x); ll n,m,k; ll tot=1,head[100100],next[100100],c[100100],to[100100]; inline void add(ll x,ll y,ll z){ to[++tot]=y;next[tot]=head[x];head[x]=tot;c[tot]=z; to[++tot]=x;next[tot]=head[y];head[y]=tot;c[tot]=0; } ll d[100010]; queue<ll>q; ll S,T; inline bool bfs(){ while(q.size())q.pop(); memset(d,0,sizeof d); d[S]=1;q.push(S); while(q.size()){ ll x=q.front();q.pop(); for(R ll i=head[x],ver;i;i=next[i]){ ver=to[i]; if(c[i]&&!d[ver]){ d[ver]=d[x]+1; q.push(ver); if(ver==T) return true; } } } return false; } inline ll dinic(ll x,ll flow){ if(x==T||!flow) return flow; ll k,rest=flow; for(R ll i=head[x],ver;i&&rest;i=next[i]){ ver=to[i]; if(d[ver]==d[x]+1&&c[i]){ k=dinic(ver,min(rest,c[i])); if(!k) d[ver]=0; c[i]-=k;c[i^1]+=k;rest-=k; } } return flow-rest; } inline ll calc(ll x,ll y){ return (x-1)*m+y+n*m; } inline bool check(ll x,ll y,ll u,ll v){ return (x-u)*(x-u)+(y-v)*(y-v)<=k*k; } ll calc1(ll x,ll y){ return (x-1)*m+y; } inline ll Read(); ll mpt[30][30]; int main(){ n=read(),m=read(),k=read(); S=n*m*2+1;T=S+1; for(R ll i=1;i<=n;i++){ for(R ll j=1;j<=m;j++){ if(mpt[i][j]=Read()){ if(i-k<=0||i+k>n||j-k<=0||j+k>m){ add(calc(i,j),T,0x7fffffff); } } } } for(R ll i=1;i<=n;i++){ for(R ll j=1;j<=m;j++){ if(mpt[i][j]){ add(calc1(i,j),calc(i,j),mpt[i][j]); for(R ll u=1;u<=n;u++){ for(R ll v=1;v<=m;v++){ if((i==u&&j==v)||!mpt[u][v]) continue; if(check(i,j,u,v)) add(calc(i,j),calc1(u,v),0x7fffffff); } } } } } ll ans=0; for(R ll i=1;i<=n;i++){ for(R ll j=1;j<=m;j++){ char c=getchar();while(c!=‘.‘&&c!=‘L‘) c=getchar(); if(c==‘L‘){ add(S,calc1(i,j),1); ans++; } } } ll _flow; while(bfs()){while(_flow=dinic(S,0x7fffffff)) ans-=_flow;} writeln(ans); } inline ll Read(){ char ch=getchar(); while(ch<‘0‘||ch>‘9‘) ch=getchar(); return ch-‘0‘; } inline ll read(){ ll x=0,t=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){ if(ch==‘-‘) t=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘){ x=x*10+ch-‘0‘; ch=getchar(); } return x*t; } inline void write(ll x){ if(x<0){putchar(‘-‘);x=-x;} if(x<=9){putchar(x+‘0‘);return;} write(x/10);putchar(x%10+‘0‘); } inline void writesp(ll x){ write(x);putchar(‘ ‘); } inline void writeln(ll x){ write(x);putchar(‘\n‘); }
标签:class std register pop front 怎么 main div while
原文地址:https://www.cnblogs.com/ylwtsq/p/13285693.html