• POJ 2195 Going Home 最小费用流


     POJ2195

    裸的最小费用流,当然也可以用KM算法解决,但是比较难写。

    注意反向边的距离为正向边的相反数(因此要用SPFA)

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=302,src=301,sink=300,INF=1e+8; 
    int n,m,man,house,x[maxn],y[maxn],cap[maxn][maxn],w[maxn][maxn];
    vector<int> next[maxn];
    
    
    void addedge(int a,int b)
    {
     next[a].push_back(b);next[b].push_back(a);
     cap[a][b]=1;cap[b][a]=0;
    }
    
    int ab(int xx)
    {
     if(xx<0)return xx*(-1);
     	else return xx;
    }
    int fa[maxn];
    int len(int a,int b)
    {
     if((a==src)||(a==sink)||(b==src)||(b==sink))return 0;
     return ab(x[b]-x[a])+ab(y[b]-y[a]);
    }
    bool inq[maxn];
    int times[maxn],dist[maxn];
    bool SPFA()
    {
     
     memset(inq,0,sizeof(inq));
     for(int i=0;i<maxn;i++)
     	dist[i]=INF;
     dist[src]=0;
     queue<int>q;
     q.push(src);
     inq[src]=true;
     while(!q.empty())
     	{
     	 int now=q.front(); 
    	 q.pop();
    	 inq[now]=false;
    	 for(int i=0;i<next[now].size();i++)
    	 	{
    	 	 int np=next[now][i];
    	 	 if((dist[np]>dist[now]+w[now][np])&&cap[now][np]>0)
    	 	 	{
    	 	 	 dist[np]=dist[now]+w[now][np];
    	 	 	 fa[np]=now;
    	 	 	 if(!inq[np]){q.push(np);inq[np]=true;}
    			}
    		}	
    	}
     if( dist[sink]<INF)return true;
     	else return false;
    }
    
    int augment()
    
    {
     int u=sink,delta=INF;
     while(u!=src)
     	{
     	 if(cap[fa[u]][u]<delta)delta=cap[fa[u]][u];
     	 u=fa[u];
    	} 
     u=sink;
     while(u!=src)
     	{
     	 cap[fa[u]][u]-=delta;
     	 cap[u][fa[u]]+=delta;
     	 u=fa[u];
    	}
     return  dist[sink]*delta;
    }
    
    int main()
    {ios::sync_with_stdio(false);
     while(cin>>n>>m)
     	{
     	 if(n==0&&m==0)return 0;
     	 man=0;house=150;
     	 memset(cap,0,sizeof(cap));memset(w,0,sizeof(w));
     	 for(int i=0;i<maxn;i++)
     	 	while(next[i].size()>0)next[i].pop_back();
     	 for(int i=0;i<n;i++)
     	 	{    
     	        
    	  		for(int j=0;j<m;j++)
     	    		{
     	    		 char c;
     	    		 cin>>c;
     	    		 if(c=='m')
     	    		 	{
     	    		 	  x[man]=i;y[man]=j;
     	    		 	  man++;
    					}
     	             if(c=='H')
     	             	{
     	             	  x[house]=i;y[house]=j;
     	             	  house++;
    					}
    				}
    		}
    	 for(int i=150;i<house;i++)
    	 	{
    	 	 addedge(i,sink);
    	 	 for(int j=0;j<man;j++)
    	 	 	addedge(j,i);
    		}
    	 for(int j=0;j<man;j++) addedge(src,j);
    	 int ans=0;
    	 for(int i=0;i<man;i++)
    	 	for(int j=150;j<house;j++)
    	 		{
    	 		 w[i][j]=len(i,j);
    	 		 w[j][i]=w[i][j]*(-1);
    			}
     	 while(SPFA())
     		{
    	 	 ans+=augment();
    		}
    	 cout<<ans<<endl;
    	}
     
     
     return 0;
    }
    

      

    ,没什么别的了,很简单。

  • 相关阅读:
    Java设计模式之单例模式
    sql查询优化整理
    MYSQL 调优学习笔记
    记一次失败的大厂面试
    ElasticSearch 6.3.2 整合 Springboot 2.1.10.RELEASE 版本,使用 Logstash 导入 mysql 数据
    ajax技术实现登录判断用户名是否重复以及利用xml实现二级下拉框联动
    浅谈 KMP 算法
    转载:Docker入门只需看这一篇就够了
    Spring Boot 监听 Activemq 中的特定 topic ,并将数据通过 RabbitMq 发布出去
    hadoop入门之海量Web日志分析 用Hadoop提取KPI统计指标
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6442095.html
Copyright © 2020-2023  润新知