標籤:class blog code ext get 2014
建圖很簡單
bfs預先處理地圖,距離就為費用
源點到所有m建邊,流量1費用0
m到所有H建邊,流量1費用為距離
H到所有匯點建邊,流量1費用0
#include<cstdio>#include<queue>#include<algorithm>#include<cstring>using namespace std;#define MAXN 10005#define MAXM 1000000#define INF 0x3f3f3f3#define getid(x,y) x*m+yint dx[]={-1,1,0,0};int dy[]={0,0,-1,1};struct node{int u,v,f,c,next;}e[MAXM];int n,m,head[MAXN],pre[MAXN],dist[MAXN],vis[MAXN],ans;bool use[105][105];int en,s,t,maxflow,mincost; //s源點,t匯點void add(int u,int v,int c,int f)//加邊{e[en].u=u;e[en].v=v;e[en].c=c;e[en].f=f;e[en].next=head[u];head[u]=en++;e[en].u=v;e[en].v=u;e[en].c=-c;e[en].f=0;e[en].next=head[v];head[v]=en++;}int spfa(){int i,u,v;for(i=0;i<=t;i++)pre[i]=-1,vis[i]=0,dist[i]=INF;dist[s]=0;vis[s]=1;queue<int>q;q.push(s);while(!q.empty()){u=q.front();q.pop();for(i=head[u];i!=-1;i=e[i].next){v=e[i].v;if(e[i].f>0&&dist[u]+e[i].c<dist[v]){dist[v]=dist[u]+e[i].c;pre[v]=i;if(!vis[v]){vis[v]=1;q.push(v);}}}vis[u]=0;}if(dist[t]==INF)return 0;return 1;}void add(){int v;int maxf=INF;for(v=pre[t];~v;v=pre[e[v].u])maxf=min(maxf,e[v].f);for(v=pre[t];~v;v=pre[e[v].u]){e[v].f-=maxf;e[v^1].f+=maxf;mincost+=e[v].c;}maxflow+=maxf;}struct pp{ int x,y,dis; pp(int a,int b) {x=a;y=b;dis=0;}};struct orz{ int id; int w; orz(int a,int b) {id=a;w=b;}};vector<orz> gg[10005];void init(){ maxflow=0; mincost=0; en=0; s=n*m; t=n*m+1; memset(head,-1,sizeof(head)); for(int i=0;i<t;i++) gg[i].clear();}char mp[105][105];bool isok(int x,int y){ return x>=0&&x<n&&y>=0&&y<m&&!use[x][y];}void bfs(pp t){ pp save=t; queue<pp> Q; Q.push(t); memset(use,0,sizeof(use)); while(!Q.empty()) { pp f=Q.front();Q.pop(); for(int d=0;d<4;d++) { t.x=f.x+dx[d]; t.y=f.y+dy[d]; t.dis=f.dis+1; if(isok(t.x,t.y)) { use[t.x][t.y]=1; Q.push(t); if(mp[t.x][t.y]=='H') { gg[getid(save.x,save.y)].push_back( orz(getid(t.x,t.y),t.dis) ); } } } }}int main(){while(scanf("%d%d",&n,&m)!=EOF){ if(n==0&&m==0) break; init(); vector<pp> v; for(int i=0;i<n;i++) { scanf("%s",mp[i]); for(int j=0;j<m;j++) { if(mp[i][j]=='m') { v.push_back(pp(i,j)); add(s,getid(i,j),0,1); } else if(mp[i][j]=='H') { add(getid(i,j),t,0,1); } } } for(int i=0;i<v.size();i++) { bfs(v[i]); int m_id=getid(v[i].x,v[i].y); for(int j=0;j<gg[m_id].size();j++) { int h_id=gg[m_id][j].id; int dis=gg[m_id][j].w; add(m_id,h_id,dis,INF); } } while(spfa()) add(); printf("%d\n",mincost);}return 0;}