• UVa 1515 Pool construction (最小割)


    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=528&page=show_problem&problem=3916

    题目大意:给定一个h*w的矩阵,每格是草地(#)或洞(.),可以花费d把一个#变成.,也可以花费f把一个.变成#,最后相邻的#和.之间要隔一个栅栏,每个花费为b.最后边界上必须全部是#,求最少花费.

    分析:- - 感觉不容易想到...首先由分隔开#和.以及花费最少,联想到最小割.设置一个s,一个t,s连所有#,权重为d,若#变成.,即把这个点分到T中去,需要把这条边割断;所有.连到t,权重为f;相邻点互相连一条边,权重为b,最后如果一个在S一个在T,则需要把这条边割断.还有边界需要是草地,故把s连到边界,权值设为无穷.最后求一下从s到t的最小割即可.

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<vector>
     5 #include<queue>
     6 typedef long long ll;
     7 using namespace std;
     8 const int maxn=2550,maxm=25500,INF=1000000;
     9 int w,h,d,f,b;
    10 
    11 struct Edge{
    12     int from,to,cap,flow;
    13     Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
    14 };
    15 
    16 struct EdmondsKarp{
    17     int n,m;
    18     vector<Edge> edges;
    19     vector<int> G[maxn];
    20     int p[maxn],a[maxn];
    21 
    22     void init(int _n){
    23         this->n=n;
    24         this->m=0;
    25         for(int i=0;i<maxn;i++)G[i].clear();
    26         edges.clear();
    27     }
    28 
    29     void AddEdge(int from,int to,int cap,int flow){
    30         edges.push_back(Edge(from,to,cap,flow));
    31         edges.push_back(Edge(to,from,0,flow));
    32         G[from].push_back(m++);
    33         G[to].push_back(m++);
    34     }
    35 
    36     ll Maxflow(int s,int t){
    37         ll flow=0;
    38         while(1){
    39             memset(a,0,sizeof(a));
    40             queue<int>Q;
    41             Q.push(s);
    42             a[s]=INF;
    43             while(!Q.empty()){
    44                 int x=Q.front();Q.pop();
    45                 for(int i=0;i<G[x].size();i++){
    46                     Edge &e=edges[G[x][i]];
    47                     if(!a[e.to]&&e.cap>e.flow){
    48                         p[e.to]=G[x][i];
    49                         a[e.to]=min(a[x],e.cap-e.flow);
    50                         Q.push(e.to);
    51                     }
    52                 }
    53                 if(a[t])break;
    54             }
    55             if(!a[t])break;
    56             for(int u=t;u!=s;u=edges[p[u]].from){
    57                 edges[p[u]].flow+=a[t];
    58                 edges[p[u]^1].flow-=a[t];
    59             }
    60             flow+=a[t];
    61         }
    62         return flow;
    63     }
    64 };
    65 
    66 int main(){
    67     int kase;
    68     long long ans=0;
    69     cin>>kase;
    70     while(kase--){
    71         ans=0;
    72         cin>>w>>h;
    73         cin>>d>>f>>b;
    74         EdmondsKarp ek;
    75         ek.init(w*h+2);
    76         char c;
    77         for(int i=0;i<w*h;i++){
    78             cin>>c;
    79             if(i/w==0||i/w==h-1||i%w==0||i%w==w-1){
    80                 if(c!='#')ans+=f;
    81                 ek.AddEdge(w*h,i,INF,0);
    82             }
    83             else if(c=='#')ek.AddEdge(w*h,i,d,0);
    84             else ek.AddEdge(i,w*h+1,f,0);
    85             if(i>0&&(i-1)/w==i/w)ek.AddEdge(i,i-1,b,0);
    86             if(i<w*h&&(i+1)/w==i/w)ek.AddEdge(i,i+1,b,0);
    87             if(i-w>=0)ek.AddEdge(i,i-w,b,0);
    88             if(i+w<w*h)ek.AddEdge(i,i+w,b,0);
    89         }
    90         ans+=ek.Maxflow(w*h,w*h+1);
    91         cout<<ans<<endl;
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    Web 2.0网站命名的7个建议
    梦猪课堂视频系列
    计算机英文术语完全介绍
    PPT高手的思路
    在线RSS阅读器大比拼
    【百度现有服务】
    转载VFW编程实例(详)
    实现MFC扩展DLL中导出类和对话框 (转)
    Windows下编译 OpenSceneGraph(转)
    OSG静态编译 (转)
  • 原文地址:https://www.cnblogs.com/7391-KID/p/6880268.html
Copyright © 2020-2023  润新知