• UVA1515 Pool construction (最小割模型)


    如果不允许转化'#'和'.'的话,那么可以直接在'#'和'.'之间连容量为b的边,把所有'#'和一个源点连接,

    所有'.'和一个汇点连接,流量不限,那么割就是建围栏(分割'#'和'.')的花费。

    问题是'#'和'.'是可以转化的,由刚才的思路,可以联想到,当'#'可以转化成'.'的时候,那么就不需要在它和周围的'.'之间建围栏,

    那么可以限制源点到'#'的容量为d,表示最多花费为d,对称地,限制'.'到汇点T容量为f。

    然后跑最大流最小割就好了。

    MinCut

    这题思路好神啊。。。仔细体会容量表示最多花费和最小割的关系

    #include<bits/stdc++.h>
    using namespace std;
    
    struct Edge
    {
        int v,cap,nxt;
    };
    const int maxv = 2502+6;
    vector<Edge> edges;
    #define PB push_back
    int head[maxv],cur[maxv];
    
    void AddEdge(int u,int v,int c)
    {
        edges.PB({v,c,head[u]});
        head[u] = edges.size()-1;
        edges.PB({u,0,head[v]});
        head[v] = edges.size()-1;
    }
    
    int S = 0,T = 1;
    int lv[maxv];
    bool vis[maxv];
    int q[maxv];
    
    bool bfs()
    {
        memset(vis,0,sizeof(vis));
        int l = 0, r = 0;
        lv[S] = 0; q[r++] = S; vis[S] = true;
        while(r>l){
            int u = q[l++];
            for(int i = head[u]; ~i; i = edges[i].nxt){
                Edge &e = edges[i];
                if(!vis[e.v] && e.cap){
                    lv[e.v] = lv[u]+1; vis[e.v] = true;
                    q[r++] = e.v;
                }
            }
        }
        return vis[T];
    }
    
    int dfs(int u,int a)
    {
        if(u == T||!a) return a;
        int flow = 0,f;
        for(int  &i = cur[u]; ~i; i = edges[i].nxt){
            Edge &e = edges[i];
            if(lv[e.v] == lv[u]+1 && (f = dfs(e.v,min(a,e.cap)))){
                flow += f;
                e.cap -= f;
                edges[i^1].cap += f;
                a -= f;
                if(!a) break;
            }
        }
        return flow;
    }
    
    const int INF = 0x3f3f3f3f;
    int MaxFlow()
    {
        int flow = 0;
        while(bfs()){
            memcpy(cur,head,sizeof(head));
            flow += dfs(S,INF);
        }
        return flow;
    }
    
    
    const int N = 50;
    char g[N][N+2];
    int id[N][N];
    int h,w;
    int d,f,b;
    
    int ID(int i,int j) { return i*w+j+2; }
    
    void init()
    {
        scanf("%d%d%d%d%d",&w,&h,&d,&f,&b);
        edges.clear();
        for(int i = 0; i < h; i++){
            scanf("%s",g[i]);
            for(int j = 0; j < w; j++){
                id[i][j] = ID(i,j);
            }
        }
         memset(head,-1,sizeof(head));
    }
    int dx[] = {0,0,1,-1};
    int dy[] = {1,-1,0,0};
    
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int TestCase; scanf("%d",&TestCase);
        while(TestCase--){
            init();
            int cost = 0;
            for(int i = 0; i < h; i++){
                for(int j = 0; j < w; j++){
                    if(i == 0 || i == h-1 || j == 0|| j == w-1){
                        if(g[i][j] == '.') cost += f;
                        AddEdge(S,id[i][j],INF);
                    }else {
                        if(g[i][j] == '#') AddEdge(S,id[i][j],d);
                        else AddEdge(id[i][j],T,f);
                    }
                    for(int k = 0; k < 4; k++){
                        int ni = i+dx[k], nj = j+dy[k];
                        if(ni<0||ni>=h||nj<0||nj>=w) continue;
                        AddEdge(id[i][j],id[ni][nj],b);
                    }
                }
            }
            printf("%d
    ",cost+MaxFlow());
        }
        return 0;
    }
  • 相关阅读:
    如何使用反射技术获取泛型类的真实类型?
    applicationContext.xml文件如何调用外部properties等配置文件
    applicationContext.xml中的使用${}是代表什么意思?
    net.sf.json.JSONException: There is a cycle in the hierarchy!错误解决方案
    MySql中LongText字段对应Hibernate映射文件的设置(转)
    ckeditor的详细配置(转)
    XML-学习
    WSDL-学习总结
    ONVIF-WSDL
    sourceinsight相关配置
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4761919.html
Copyright © 2020-2023  润新知