题目大意:有一些车和一些修车的人,给出每个人修每个车的时间,问所有人等待的最短平均时间是多少。
思路:记得POJ有一个和这个很像的题,做法是一样的。对于每个人修车的时候,我们只考虑他修车的时间对在它之后修车的人的时间的影响,因此我们只要考虑每一辆车是倒数第几个修的就可以了,然后朴素的建图,跑朴素的费用流,就可以过。
CODE:
#include <queue> #include <cstdio> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define MAX 800 #define MAXE 100010 #define INF 0x3f3f3f3f #define S 0 #define T (MAX - 1) using namespace std; int shopper,cars; int src[MAX][MAX]; int head[MAX],total = 1; int next[MAXE],aim[MAXE],cost[MAXE],flow[MAXE]; int f[MAX],from[MAX],p[MAX]; bool v[MAX]; inline void Add(int x,int y,int f,int c) { next[++total] = head[x]; aim[total] = y; flow[total] = f; cost[total] = c; head[x] = total; } inline void Insert(int x,int y,int f,int c) { Add(x,y,f,c); Add(y,x,0,-c); } inline bool SPFA() { static queue<int> q; while(!q.empty()) q.pop(); q.push(S); memset(v,false,sizeof(v)); memset(f,0x3f,sizeof(f)); f[S] = 0; while(!q.empty()) { int x = q.front(); q.pop(); v[x] = false; for(int i = head[x]; i; i = next[i]) if(flow[i] && f[aim[i]] > f[x] + cost[i]) { f[aim[i]] = f[x] + cost[i]; if(!v[aim[i]]) { v[aim[i]] = true; q.push(aim[i]); } from[aim[i]] = x; p[aim[i]] = i; } } return f[T] != INF; } int EdmondsKarp() { int re = 0; while(SPFA()) { int remain_flow = INF; for(int i = T; i != S; i = from[i]) remain_flow = min(remain_flow,flow[p[i]]); for(int i = T; i != S; i = from[i]) { flow[p[i]] -= remain_flow; flow[p[i]^1] += remain_flow; } re += remain_flow * f[T]; } return re; } int main() { cin >> shopper >> cars; for(int i = 1; i <= cars; ++i) for(int j = 1; j <= shopper; ++j) scanf("%d",&src[i][j]); for(int i = 1; i <= cars; ++i) Insert(S,i,1,0); for(int i = 1; i <= cars; ++i) for(int j = 1; j <= shopper; ++j) for(int k = 1; k <= cars; ++k) Insert(i,j * cars + k,1,src[i][j] * k); for(int i = 1; i <= shopper; ++i) for(int j = 1; j <= cars; ++j) Insert(i * cars + j,T,1,0); cout << fixed << setprecision(2) << (double)EdmondsKarp() / cars << endl; return 0; }