UVa10746 Crime Wave - The Sequel

来源:互联网 发布:如何选笔记本电脑 知乎 编辑:程序博客网 时间:2024/06/15 03:32

        题意:n个银行,m个警察(n<=m)。每个银行需要一个警察去守。给出所有警察到所有银行的花费,问怎么安排警察最省。

        思路:最小费用最大流。建图:源点->银行->警察->汇点。注意反向边费用要赋上正向边的相反数,另外可能出现精度问题。这道题本来是简单题,但是我把return 0写成了return true,RE一万年找不出原因。。。

#include <iostream>#include <stdio.h>#include <cmath>#include <algorithm>#include <iomanip>#include <cstdlib>#include <string>#include <memory.h>#include <vector>#include <queue>#include <stack>#include <ctype.h>#define INF 1000000000using namespace std;int n,m;int map[50][50];int f[50][50];double cost[50][50];int pre[50];int main(){while(cin>>n>>m){if(n==0&&m==0)break;memset(map,0,sizeof(map));memset(f,0,sizeof(f));for(int i=0;i<=n+m+1;i++)for(int j=0;j<=n+m+1;j++)cost[i][j]=0;//for(int i=1;i<=n;i++)map[0][i]=1;for(int i=1;i<=m;i++)map[n+i][n+m+1]=1;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>cost[i][n+j];cost[n+j][i]=-cost[i][n+j];map[i][n+j]=1;}}double cc[50];bool vis[50];double ans=0;for(int k=1;k<=n;k++){memset(vis,0,sizeof(vis));for(int i=1;i<=m+n+1;i++)cc[i]=INF;cc[k]=0;queue<int> que;que.push(k);while(!que.empty()){int cur=que.front();que.pop();vis[cur]=false;for(int i=1;i<=n+m+1;i++){if( (cc[cur]+cost[cur][i])<cc[i]-0.0001 &&(map[cur][i]-f[cur][i])>0 ){pre[i]=cur;cc[i]=(cc[cur]+cost[cur][i]);if(!vis[i]){vis[i]=true;que.push(i);}}}}ans+=cc[n+m+1];for(int i=n+m+1;i!=k;i=pre[i]){f[pre[i]][i]++;f[i][pre[i]]--;}}printf("%.2lf\n",ans/n-0.00000001);}return 0;}


0 0