zoukankan      html  css  js  c++  java
  • POJ2195:Going Home——题解

    http://poj.org/problem?id=2195

    题目大意:

    有些人和房子,一个人只能进一个房子,人走到房子的路程即为代价。

    求所有人走到房子后的最小代价。

    ——————————————————

    bfs处理每个人到每个房的最短路之后就是裸的费用流了,不解释。

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    using namespace std;
    typedef long long ll;
    const int INF=1e9;
    const int N=10010;
    const int M=22000;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    struct node{
        int nxt;
        int to;
        int w;
        int b;
    }edge[M];
    int head[N],cnt=-1;
    void add(int u,int v,int w,int b){
        cnt++;
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].b=b;
        edge[cnt].nxt=head[u];
        head[u]=cnt;
        return;
    }
    int dis[N];
    bool vis[N];
    inline bool spfa(int s,int t,int n){
        deque<int>q;
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++)dis[i]=INF;
        dis[t]=0;q.push_back(t);vis[t]=1;
        while(!q.empty()){
        int u=q.front();
        q.pop_front();vis[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].nxt){
            int v=edge[i].to;
            int b=edge[i].b;
            if(edge[i^1].w&&dis[v]>dis[u]-b){
            dis[v]=dis[u]-b;
            if(!vis[v]){
                vis[v]=1;
                if(!q.empty()&&dis[v]<dis[q.front()]){
                q.push_front(v);
                }else{
                q.push_back(v);
                }
            }
            }
        }
        }
        return dis[s]<INF;
    }
    int ans=0;
    int dfs(int u,int flow,int m){
        if(u==m){
        vis[m]=1;
        return flow;
        }
        int res=0,delta;
        vis[u]=1;
        for(int e=head[u];e!=-1;e=edge[e].nxt){
            int v=edge[e].to;
        int b=edge[e].b;
            if(!vis[v]&&edge[e].w&&dis[u]-b==dis[v]){
                delta=dfs(v,min(edge[e].w,flow-res),m);
                if(delta){
                    edge[e].w-=delta;
                    edge[e^1].w+=delta;
                    res+=delta;
            ans+=delta*b;
                    if(res==flow)break;
                }
            }
        }
        return res;
    }
    inline int costflow(int S,int T,int n){
        while(spfa(S,T,n)){
        do{
            memset(vis,0,sizeof(vis));
            dfs(S,INF,T);
        }while(vis[T]);
        }
        return ans;
    }
    int num1=0,num2=0;
    int mp[101][101];
    int pos[101][101];
    int pdis[101][101];
    bool walk[101][101];
    int dx[4]={0,-1,0,1};
    int dy[4]={1,0,-1,0};
    void bfs(int xx,int yy,int n,int m){
        queue<int>q1,q2,q3,q4;
        memset(walk,0,sizeof(walk));
        memset(pdis,127,sizeof(pdis));
        pdis[xx][yy]=0;
        q1.push(xx);q2.push(yy);
        walk[xx][yy]=1;
        while(!q1.empty()){
        int x=q1.front(),y=q2.front();
        q1.pop(),q2.pop();
        if(mp[x][y]>0){
            q3.push(x);q4.push(y);
        }
        for(int i=0;i<4;i++){
            int nx=x+dx[i],ny=y+dy[i];
            if(nx<=0||ny<=0||nx>n||ny>m||walk[nx][ny])continue;
            walk[nx][ny]=1;
            pdis[nx][ny]=pdis[x][y]+1;
            q1.push(nx);q2.push(ny);
        }
        }
        while(!q3.empty()){
        int nx=q3.front(),ny=q4.front();
        q3.pop();q4.pop();
        add(pos[xx][yy],mp[nx][ny]+num1,1,pdis[nx][ny]);
        add(mp[nx][ny]+num1,pos[xx][yy],0,-pdis[nx][ny]);
        }
        return;
    }
    void restart(){
        memset(head,-1,sizeof(head));
        memset(mp,0,sizeof(mp));
        memset(pos,0,sizeof(pos));
        cnt=-1;
        ans=0;
        num1=0;
        num2=0;
        return;
    }
    int main(){
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF&&n&&m){
        restart();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
            char ch;
            cin>>ch;
            if(ch=='m'){
                num1++;
                mp[i][j]=-1;
                pos[i][j]=num1;
            }else if(ch=='H'){
                num2++;
                mp[i][j]=num2;
            }
            }
        }
        int S=num1+num2+1,T=S+1;
        for(int i=1;i<=num1;i++){
            add(S,i,1,0);
            add(i,S,0,0);
        }
        for(int i=1;i<=num2;i++){
            add(i+num1,T,1,0);
            add(T,i+num1,0,0);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
            if(mp[i][j]==-1){
                bfs(i,j,n,m);
            }
            }
        }
        printf("%d
    ",costflow(S,T,T));
        }
        return 0;
    }
  • 相关阅读:
    基于Metaweblog API 接口一键发布到国内外主流博客平台
    uva144 Student Grants
    Uva 10452
    Uva 439 Knight Moves
    Uva 352 The Seasonal War
    switch语句
    java——基础知识
    我的lua学习2
    codeforces 431 D. Random Task 组合数学
    codeforces 285 D. Permutation Sum 状压 dfs打表
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/7953786.html
Copyright © 2011-2022 走看看