zoj1654
Posted gaudar
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了zoj1654相关的知识,希望对你有一定的参考价值。
各行各列连续的o和*记为一个元素。然后记录下开始和结束位置。如果横条和竖条交点为‘o‘。连线。表示两边能选一边,然后最大流。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <iomanip> #include <cstring> #include <map> #include <queue> #include <set> #include <cassert> #include <stack> #include <bitset> //#include <unordered_set> #define mkp make_pair #define err cout<<"here"<<endl using namespace std; const double EPS=1e-12; typedef long long lon; typedef unsigned long long ull; typedef map<ull,int>::iterator IT; const lon SZ=2510,SSZ=1000010,APB=4,mod=100000,one=97; const lon INF=0x7FFFFFFF; lon n,m,knum,cnt,S=2507,T=2508; struct nd{ lon to,wt; nd(lon a=0,lon b=0):to(a),wt(b){} }; int dep[SZ],bg[SZ],fn[SZ],bel[SZ]; int nex[SSZ],head[SZ],wt[SSZ],to[SSZ]; char ch[SZ][SZ]; void add(int u,int v,int w) { ++cnt; nex[cnt]=head[u]; head[u]=cnt; to[cnt]=v,wt[cnt]=w; } int gid(int x,int y) { if(y==0)return x; else if(y==1)return x+n; else return x+n+m+1; } void init() { cnt=-1; memset(head,-1,sizeof(head)); // memset(bel,0,sizeof(bel)); // memset(bg,0,sizeof(bg)); // memset(fn,0,sizeof(fn)); cin>>n>>m; for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j)cin>>ch[i][j]; } int rnum=0,cnum=0; bool csc=0; for(int i=1;i<=n;++i) { for(int j=1;j<=m+1;++j) { if(ch[i][j]!=‘#‘&&j!=m+1&&!csc) { ++rnum; csc=1; bg[rnum]=j; bel[rnum]=i; } if((ch[i][j]==‘#‘||j==m+1)&&csc) { fn[rnum]=j-1; csc=0; } } } csc=0; for(int j=1;j<=m;++j) { for(int i=1;i<=n+1;++i) { if((ch[i][j]!=‘#‘&&i!=n+1)&&!csc) { ++cnum; csc=1; bg[rnum+cnum]=i; bel[rnum+cnum]=j; } if((ch[i][j]==‘#‘||i==n+1)&&csc) { fn[rnum+cnum]=i-1; csc=0; } } } for(int i=1;i<=rnum;++i) { for(int j=rnum+1;j<=rnum+cnum;++j) { bool ok=0; int x=bel[i],y=bel[j]; ok|=ch[x][y]==‘o‘; ok&=bg[i]<=y&&y<=fn[i]; ok&=bg[j]<=x&&x<=fn[j]; if(ok) { add(i,j,1); add(j,i,0); } } } for(int i=1;i<=rnum;++i) { add(S,i,1); add(i,S,0); } for(int i=1+rnum;i<=cnum+rnum;++i) { add(i,T,1),add(T,i,0); } //cout<<rnum<<" "<<cnum<<endl; } bool bfs() { memset(dep,0,sizeof(dep)); queue<int> q; q.push(S); dep[S]=1; for(;q.size();) { int fr=q.front(); q.pop(); for(int i=head[fr];i!=-1;i=nex[i]) { int t=to[i],w=wt[i]; if(!dep[t]&&w) { dep[t]=dep[fr]+1; q.push(t); } } } return dep[T]; } int dinic(int x,int flow) { if(x==T)return flow; else { int rem=flow; for(int i=head[x];i!=-1&&rem;i=nex[i]) { int t=to[i],w=wt[i]; if(dep[t]==dep[x]+1&&w) { int tmp=dinic(t,min(rem,w)); if(tmp==0)dep[t]=0; rem-=tmp; wt[i]-=tmp; wt[i^1]+=tmp; } } return flow-rem; } } void work() { int res=0; for(;bfs();res+=dinic(S,INF)); cout<<res<<endl; } void release() { for(int i=1;i<=n;++i) { for(int j=1;j<=m;++j) ch[i][j]=0; } } int main() { std::ios::sync_with_stdio(0); //freopen("d:\\1.txt","r",stdin); lon casenum; cin>>casenum; //cout<<casenum<<endl; for(lon time=1;time<=casenum;++time) //for(lon time=1;cin>>n,n;++time) { cout<<"Case :"<<time<<endl; init(); work(); release(); } return 0; }
以上是关于zoj1654的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ 1654--Place the Robots二分匹配 && 经典建图