近日好不容易在自救之路写完暑训遗留下来的网络流8题,在此回顾一下。

Going Home POJ - 2195 

题意:m要去H,一个H只能容纳一个m,一步一块钱,问最小花费。

思路:最小费用最大流的板子题。有博客用了Dijkstra,不过在我看来,存在负权边的图是不能使用Dijkstra的,所以虽然我曾立誓再也不写SPFA,现在也不得不屈服了。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<vector>
  4 #include<stack>
  5 #include<queue>
  6 #include<map>
  7 #include<set>
  8 #include<cstdio>
  9 #include<cstring>
 10 #include<cmath>
 11 #include<ctime>
 12 #define fuck(x) cout<<#x<<" = "<<x<<endl;
 13 #define ls (t<<1)
 14 #define rs ((t<<1)+1)
 15 using namespace std;
 16 typedef long long ll;
 17 typedef unsigned long long ull;
 18 const int maxn = 1024;
 19 const int inf = 2.1e9;
 20 const ll Inf = 999999999999999999;
 21 const int mod = 1000000007;
 22 const double eps = 1e-6;
 23 const double pi = acos(-1);
 24 int n,m;
 25 char mp[108][108];
 26 struct node
 27 {
 28     int x,y;
 29 }p1[maxn],p2[maxn];
 30 int Head[maxn],Next[maxn*maxn],v[maxn*maxn],w[maxn*maxn],cap[maxn*maxn],cnt;
 31 int t1,t2;int ans;
 32 void init()
 33 {
 34     t1=1;cnt=t2=ans=0;
 35     memset(Head,-1,sizeof(Head));
 36 }
 37 
 38 void add(int x,int y,int z,int f){
 39 //    cout<<x<<" "<<y<<" "<<z<<endl;
 40     v[cnt]=y;
 41     w[cnt]=z;
 42     cap[cnt]=f;
 43     Next[cnt]=Head[x];
 44     Head[x]=cnt++;
 45 
 46     v[cnt]=x;
 47     w[cnt]=-z;
 48     cap[cnt]=0;
 49     Next[cnt]=Head[y];
 50     Head[y]=cnt++;
 51 }
 52 bool vis[maxn];
 53 int dis[maxn];
 54 int prevv[maxn],preve[maxn];
 55 int s,t;
 56 bool spfa()
 57 {
 58     queue<int>q;
 59     memset(vis,0,sizeof(vis));
 60     for(int i=1;i<=t;i++){
 61         dis[i]=inf;
 62     }
 63 
 64     dis[s]=0;
 65     q.push(s);
 66     while(!q.empty()){
 67         int u=q.front();
 68         q.pop();
 69         vis[u]=false;
 70         for(int k=Head[u];k!=-1;k=Next[k]){
 71             if(cap[k]&&dis[v[k]]>dis[u]+w[k]){
 72                 dis[v[k]]=dis[u]+w[k];
 73                 prevv[v[k]]=u;
 74                 preve[v[k]]=k;
 75 
 76                 if(!vis[v[k]]){
 77                     vis[v[k]]=true;
 78                     q.push(v[k]);
 79                 }
 80             }
 81         }
 82     }
 83     if(dis[t]==inf){return false;}
 84     else return true;
 85 }
 86 int min_cost_flow()
 87 {
 88     while(spfa()){
 89         for(int i=t;i!=s;i=prevv[i]){
 90             int k=preve[i];
 91             cap[k]-=1;
 92             cap[k^1]+=1;
 93         }
 94         ans+=dis[t];
 95     }
 96 
 97 }
 98 
 99 int main()
100 {
101 //    ios::sync_with_stdio(false);
102 //    freopen("in.txt","r",stdin);
103 
104     while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){
105         init();
106         for(int i=1;i<=n;i++){
107             scanf("%s",mp[i]+1);
108             for(int j=1;j<=m;j++){
109                 if(mp[i][j]=='m'){p1[++t1]=node{i,j};}
110                 else if(mp[i][j]=='H'){p2[++t2]=node{i,j};}
111             }
112         }
113         s=1;t=t1+t2+1;
114         for(int i=2;i<=t1;i++){
115             add(s,i,0,1);
116             for(int j=1;j<=t2;j++){
117                 add(i,j+t1,abs(p1[i].x-p2[j].x)+abs(p1[i].y-p2[j].y),inf);
118             }
119         }
120         for(int i=1;i<=t2;i++){
121             add(i+t1,t,0,1);
122         }
123 
124         min_cost_flow();
125         printf("%d\n",ans);
126     }
127 
128     return 0;
129 }
View Code

相关文章:

  • 2022-12-23
  • 2021-07-20
猜你喜欢
  • 2021-07-29
  • 2021-10-22
  • 2021-07-28
  • 2022-01-01
相关资源
相似解决方案