04年论文题《黄源河--浅谈图论模型的建立与应用》
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int inf=1e9; struct Edge{int to,next,v;}e[200005]; int head[5005],cnt,d[5005]; void ins(int u,int v,int w){ e[++cnt]=(Edge){v,head[u],w};head[u]=cnt; } void insert(int u,int v,int w){ ins(u,v,w);ins(v,u,0); } bool bfs(int s,int t){ memset(d,-1,sizeof(d)); d[s]=0;queue<int>q;q.push(s); while(!q.empty()){ int u=q.front();q.pop(); for(int i=head[u];i;i=e[i].next) if(e[i].v&&d[e[i].to]==-1){ d[e[i].to]=d[u]+1; q.push(e[i].to); } } return d[t]!=-1; } int dfs(int x,int f,int t){ if(x==t)return f; int w,flow=0; for(int i=head[x];i;i=e[i].next) if(e[i].v&&d[e[i].to]==d[x]+1){ w=dfs(e[i].to,min(f-flow,e[i].v),t); e[i].v-=w;e[i^1].v+=w;flow+=w; if(flow==f)return f; } if(!flow)d[x]=-1; return flow; } int dinic(int s,int t){int ans=0;while(bfs(s,t))ans+=dfs(s,inf,t);return ans;} int id1[55][55],id2[55][55],tot1,tot2; void init(){ memset(head,0,sizeof(head));cnt=1; memset(id1,0,sizeof(id1)); memset(id2,0,sizeof(id2)); tot1=tot2=0; } char mp[55][55]; int main(){ //freopen("a.in","r",stdin); int cas;scanf("%d",&cas); for(int kase=1;kase<=cas;kase++){ int n,m;scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%s",mp[i]+1); init(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(mp[i][j]!='#'){ bool flag=false; int now=j; while(now<=m&&mp[i][now]!='#')if(mp[i][now++]=='o')flag=true; if(flag){ tot1++; while(j<=m&&mp[i][j]!='#')id1[i][j++]=tot1; } } for(int j=1;j<=m;j++) for(int i=1;i<=n;i++) if(mp[i][j]!='#'){ bool flag=false; int now=i; while(now<=n&&mp[now][j]!='#')if(mp[now++][j]=='o')flag=true; if(flag){ tot2++; while(i<=n&&mp[i][j]!='#')id2[i++][j]=tot2; } } int S=0,T=tot1+tot2+1; for(int i=1;i<=tot1;i++)insert(S,i,1); for(int i=1;i<=tot2;i++)insert(i+tot1,T,1); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(mp[i][j]=='o'&&id1[i][j]&&id2[i][j]) insert(id1[i][j],id2[i][j]+tot1,1); printf("Case :%d\n%d\n",kase,dinic(S,T)); } return 0; }