poj3686 Windys

传送门

费用流写起来怪怪的

就是感觉特别暴力 估计学一下势优化能快一点qwq

题意:

给定n个任务和m个机器 每一台机器加工指定的物品需要一定的时间

问n件物品加工所需最短时间

Solution:

这个题一看是没有办法贪心的

dp的话样例就否决了

扫描二维码关注公众号,回复: 4246036 查看本文章

最小割没法转

所以考虑跑一个费用流

建图就非常简单 每个物品每个点每个时间全分开 n^3边 n^2点建图就可以了

反正n<=50 而且图肯定流的非常少

(就是数组稍微开大点)

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<queue>
 6 #define ms(a,b) memset(a,b,sizeof a)
 7 #define rep(i,a,n) for(int i = a;i <= n;i++)
 8 #define per(i,n,a) for(int i = n;i >= a;i--)
 9 #define inf 2147483647
10 using namespace std;
11 typedef long long ll;
12 typedef double D;
13 #define eps 1e-8
14 ll read() {
15     ll as = 0,fu = 1;
16     char c = getchar();
17     while(c < '0' || c > '9') {
18         if(c == '-') fu = -1;
19         c = getchar();
20     }
21     while(c >= '0' && c <= '9') {
22         as = as * 10 + c - '0';
23         c = getchar();
24     }
25     return as * fu;
26 }
27 const int N = 4005;
28 const int M = 400003;
29 //head
30 int s = N-1,t = N-2;
31 int head[N],nxt[M],mo[M],cnt = 1;
32 ll cst[M],flw[M];
33 void _add(int x,int y,ll w,ll f) {
34     nxt[++cnt] = head[x];
35     head[x] = cnt;
36     mo[cnt] = y,cst[cnt] = w,flw[cnt] = f;
37 }
38 void add(int x,int y,ll w,ll f) {
39     if(x^y) _add(x,y,w,f),_add(y,x,-w,0);
40 }
41 
42 ll dis[N],flow[N];
43 bool vis[N];
44 int pre[N],lst[N];
45 bool spfa() {
46     queue<int> q;
47     ms(dis,60),ms(flow,60),ms(vis,0);
48     q.push(s),dis[s] = 0,vis[s] = 1;
49     pre[t] = 0;
50     while(!q.empty()) {
51         int x = q.front();
52         q.pop(),vis[x] = 0;
53         for(int i = head[x];i;i = nxt[i]) {
54             int sn = mo[i];
55             if(dis[sn] > dis[x] + cst[i] && flw[i]) {
56                 dis[sn] = dis[x] + cst[i];
57                 pre[sn] = x,lst[sn] = i;
58                 flow[sn] = min(flow[x],flw[i]);
59                 if(!vis[sn]) q.push(sn),vis[sn] = 1;
60             }
61         }
62     }
63 
64     return pre[t];
65 }
66 
67 ll maxx,minn;
68 void MCMF() {
69     maxx = 0,minn = 0;
70     while(spfa()) {
71         int x = t;
72         maxx += flow[t],minn += flow[t] * dis[t];
73         while(x ^ s) {
74             flw[lst[x]] -= flow[t];
75             flw[lst[x] ^ 1] += flow[t];
76             x = pre[x];
77         }
78     }
79 }
80 int n,m;
81 int a[55][55];
82 void solve() {
83     ms(head,0),cnt = 1;
84     n = read(),m = read();
85     rep(i,1,n) rep(j,1,m) a[i][j] = read();
86     rep(i,1,n) add(s,i,0,1);
87     rep(i,n+1,n+n*m) add(i,t,0,1);
88     rep(i,1,n) rep(j,1,m) rep(k,1,n) {
89         add(i,j*n+k,k * a[i][j],1);
90     }
91     MCMF();
92     printf("%.6lf\n",minn * 1.0 / (D)n);
93 }
94 
95 int main() {
96     int T = read();
97     while(T--) solve();
98     return 0;
99 }

猜你喜欢

转载自www.cnblogs.com/yuyanjiaB/p/10022556.html
POJ
今日推荐