标签:bsp evel from level read c++ 最小割 == dfs
题目:BZOJ1412、洛谷P2598、Vijos P1555、codevs2351。
题目大意:有一个nm矩阵,每格里住着狼、羊或其他动物。现在要你建最少的篱笆,使得狼和羊分开。问最少建多长的篱笆。
解题思路:网络流最小割问题,求最大流即可。
首先建超级源点S=0,超级汇点T=nm+1。对于每只狼,从S到这只狼连接容量inf的边;对于每只羊,从这只羊到T连接容量inf的边。
然后,对于每个点,若该点不是羊,则从该点向它四个方向所有不是狼的点连接容量为1的边。
建完图后就是裸的最大流问题,用Dinic、ISAP等都可,EK应该也可。
我用的是Dinic。
C++ Code:
#include<stdio.h>
#include<cctype>
#include<vector>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
int n,m,level[30003],iter[30003],a[103][103];
struct edges{
int to,cap,rev;
};
vector<edges>G[200003];
queue<int>q;
inline int readint(){
int p=0;
char c=getchar();
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())p=p*10+c-‘0‘;
return p;
}
inline void addedge(int from,int to,int cap){
G[from].push_back((edges){to,cap,G[to].size()});
G[to].push_back((edges){from,0,G[from].size()-1});
}
void bfs(int s){
memset(level,-1,sizeof(level));
level[s]=0;
q.push(s);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<G[u].size();++i){
edges& e=G[u][i];
if(level[e.to]<0&&e.cap>0){
level[e.to]=level[u]+1;
q.push(e.to);
}
}
}
}
int dfs(int u,int t,int f){
if(u==t)return f;
for(int& i=iter[u];i<G[u].size();++i){
edges& e=G[u][i];
if(e.cap>0&&level[e.to]>level[u]){
int d=dfs(e.to,t,min(f,e.cap));
if(d){
e.cap-=d;
G[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
int max_flow(int s,int t){
int flow=0;
while(1){
bfs(s);
if(level[t]<0)return flow;
memset(iter,0,sizeof(iter));
int f;
while(f=dfs(s,t,INF))flow+=f;
}
}
int main(){
memset(a,-1,sizeof a);
n=readint(),m=readint();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)a[i][j]=readint();
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j){
if(a[i][j]==1)addedge(0,(i-1)*m+j,INF);else
if(a[i][j]==2)
addedge((i-1)*m+j,n*m+1,INF);
if(a[i][j]==2)continue;
if(a[i+1][j]==2||a[i+1][j]==0)addedge((i-1)*m+j,i*m+j,1);
if(a[i-1][j]==2||a[i-1][j]==0)addedge((i-1)*m+j,(i-2)*m+j,1);
if(a[i][j+1]==2||a[i][j+1]==0)addedge((i-1)*m+j,(i-1)*m+j+1,1);
if(a[i][j-1]==2||a[i][j-1]==0)addedge((i-1)*m+j,(i-1)*m+j-1,1);
}
printf("%d\n",max_flow(0,n*m+1));
return 0;
}
标签:bsp evel from level read c++ 最小割 == dfs
原文地址:http://www.cnblogs.com/Mrsrz/p/7612076.html