uva 10746 Crime Wave - The Sequel (最小费用流)

Problem G

Crime Wave – The Sequel

Input: Standard Input

Output: Standard Output

Time Limit: 2 Seconds

 

n banks have been robbed this fine day. (greater than or equal to n) police cruisers are on duty at various locations in the city. n of the cruisers should be dispatched, one to each of the banks, so as to minimize the average time of arrival at the n banks.

 

Input

The input file contains several sets of inputs. The description of each set is given below:

The first line of input contains 0 < n <= m <= 20n lines follow, each containing m positive real numbers: the travel time for cruiser m to reach bank n.

Input is terminated by a case where m=n=0. This case should not be processed.  

Output

For each set of input output a single number: the minimum average travel time, accurate to 2 fractional digits.

 

Sample Input                             Output for Sample Input

3 4
10.0 23.0 30.0 40.0
5.0 20.0 10.0 60.0
18.0 20.0 20.0 30.0

0 0

13.33


Problemsetter: Gordon Cormack, EPS



题目大意:

m个警察赶到 n 个银行,已知各个时间,以及m>=n,求平均时间最短

解题思路:

平均时间最短,也就是总时间最短,很明显想到费用流,带权匹配KM算法也可以解。很裸的一题最小费用流

但是WA了一次,原因是居然卡精度,最后答案加了eps就AC了,感觉是UVA的数据有问题。

代码:

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn=110;
const int inf=(1<<30);
const double eps=1e-8;
struct edge{
	int u,v,next,f;
	double c;
	edge(int u0=0,int v0=0,int f0=0,double c0=0,int next0=0){
		u=u0,v=v0,f=f0,c=c0,next=next0;
	}
}e[maxn*maxn*10];
int head[maxn*2],visited[maxn*2],path[maxn*2];
double dist[maxn*2],c[maxn][maxn];
int cnt,from,to,marked,n,m;

void initial(){
	cnt=0;marked=1;
	from=0;to=n+m+1;
	memset(head,-1,sizeof(head));
	memset(visited,0,sizeof(visited));
}

void adde(int u,int v,int f,double c){
	e[cnt].u=u,e[cnt].v=v,e[cnt].f=f,e[cnt].c=c,e[cnt].next=head[u],head[u]=cnt++;
	e[cnt].u=v,e[cnt].v=u,e[cnt].f=0,e[cnt].c=-c,e[cnt].next=head[v],head[v]=cnt++;
}

void input(){
	double c0;
	for(int i=1;i<=m;i++) adde(from,i,1,0);
	for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf("%lf",&c0);
            adde(j,i+m,1,c0);
        }
	}
	for(int i=1;i<=n;i++) adde(i+m,to,1,0);
}

void bfs(){
	 for(int i=0;i<=to;i++){
	 	dist[i]=inf;
	 	path[i]=-1;
	 }
	 dist[from]=0;
     queue <int> q;
     q.push(from);
     marked++;
     visited[from]=marked;
     while(!q.empty()){
         int s=q.front();
         q.pop();
         for(int i=head[s];i!=-1;i=e[i].next){
              int d=e[i].v;
              if(e[i].f>0 && dist[s]+e[i].c+eps<dist[d]){
                 dist[d]=dist[s]+e[i].c;
                 path[d]=i;
                 if(visited[d]!=marked){
                 	visited[d]=marked;
                 	q.push(d);
                 }
              }
         }
         visited[s]=-1;
     }
}

void solve(){
	double ans=0;
	for(int i=0;i<n;i++){
    	bfs();
    	if(path[to]==-1) break;
		ans+=dist[to];
		for(int i=to;i!=from;i=e[path[i]].u){
     		e[path[i]].f-=1;
        	e[path[i]^1].f+=1;
    	}
    }
	printf("%.2lf\n",ans/(double)n+eps);
}

int main(){
    //freopen("in.txt","r",stdin);
	while(scanf("%d%d",&n,&m)!=EOF && (n||m) ){
		initial();
		input();
		solve();
	}
	return 0;
}



posted @ 2014-04-17 00:13  炒饭君  阅读(195)  评论(0编辑  收藏  举报