[bzoj1066] [SCOI2007]蜥蜴
一道比较裸的网络流...
还在建图,就惨遭ditoly爆D:"这么裸的题,还要做啊?"
---------分割线
每一个点拆3个点,表示跳出去的时候的高度,然后每个点再拆两个点,中间连1的边,表示只能有一只蜥蜴从这个点跳出去....
然后就没啦。
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #define S 0 #define T 20001 #define INF 2000000000 using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m,d,cnt=1,ans=0; char st[55],s[55][55]; int num[2][5][2506]; int dis[4][20][2]; int q[20005]; struct edge{ int to,next,w; }e[8000005]; int head[20005]; queue<int> qu; inline int abs(int x) {return x<0?-x:x;} void INS(int f,int t,int w) { e[++cnt].next=head[f];head[f]=cnt; e[cnt].to=t;e[cnt].w=w; } void ins(int f,int k,int t,int k2,int w) { //cout<<"ins"<<f<<" "<<k<<" "<<t<<" "<<k2<<" "<<w<<endl; int x1=(f!=S)?num[1][k][f]:S; int x2=(t!=T)?num[0][k2][t]:T; INS(x1,x2,w); INS(x2,x1,0); } void init() { int cc=0; for(int i=0;i<2;i++) for(int j=0;j<4;j++) for(int k=1;k<=2500;k++) num[i][j][k]=++cc; } int dfs(int x,int f) { if(x==T) return f; int used=0; for(int i=head[x];i;i=e[i].next) if(e[i].w&&q[e[i].to]==q[x]+1) { int w=dfs(e[i].to,min(e[i].w,f-used)); e[i].w-=w; used+=w; e[i^1].w+=w; if(used==f) return f; } if(!used) q[x]=-1; return used; } bool bfs() { memset(q,0,sizeof(q)); q[S]=1;qu.push(S); while(!qu.empty()) { int x=qu.front();qu.pop(); for(int i=head[x];i;i=e[i].next) if(e[i].w&&!q[e[i].to]) { q[e[i].to]=q[x]+1; qu.push(e[i].to); } } return q[T]!=0; } int main() { n=read();m=read();d=read();init(); for(int i=1;i<=n;i++) scanf("%s",s[i]+1); for(int i=1;i<=2500;i++) for(int k=0;k<4;k++) {INS(num[0][k][i],num[1][k][i],1);INS(num[1][k][i],num[1][k][i],0);} for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { for(int k=max(1,i-d);k<=min(i+d,n);k++) for(int l=max(1,j-d+abs(k-i));l<=min(m,j+d-abs(k-i));l++) if(k!=i||l!=j) for(int q=0;q<s[i][j]-'0';q++) for(int p=0;p<s[k][l]-'0';p++) ins((i-1)*m+j,q,(k-1)*m+l,p,1); if(i<=d||i+d>n||j<=d||j+d>m) for(int k=0;k<s[i][j]-'0';k++) ins((i-1)*m+j,k,T,0,1); } for(int i=1;i<=n;i++) { scanf("%s",st+1); for(int j=1;j<=m;j++) if(st[j]!='.') ins(S,0,(i-1)*m+j,s[i][j]-'0'-1,1),ans++; } while(bfs()) ans-=dfs(S,INF); cout<<ans; return 0; }
FallDream代表秋之国向您问好!
欢迎您来我的博客www.cnblogs.com/FallDream