zoukankan      html  css  js  c++  java
  • poj3686 Windys

    传送门

    费用流写起来怪怪的

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

    题意:

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

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

    Solution:

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

    dp的话样例就否决了

    最小割没法转

    所以考虑跑一个费用流

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

    -----Update on 11.27-------

    重新看了一遍题发现好像没有之前想的那么水...

    n^2点指的是n件物品 m*n表示m时间做了n工作

    然后之前对于每个物品统计时间 变成第a[i][j]这个时间被用了多少次

    至于点坐标反过来就行 也就是代码里面的k表示是倒数第k件

    由于spfa显然不会有空的...

    极限的时间复杂度是n^5 但是这个上界非常松 甚至达不到n^4 所以时间没什么压力

    ----------------------------------

    反正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
    ",minn * 1.0 / (D)n);
    93 }
    94 
    95 int main() {
    96     int T = read();
    97     while(T--) solve();
    98     return 0;
    99 }
  • 相关阅读:
    一个简易邮件群发软件设计与实现
    一种公众号回复关键词机制
    Oracle 异常 ORA-01861: literal does not match format string(字符串格式不匹配)
    Linux使用命令
    IDEA在引入Maven项目后Dependencies中在出现红色波浪线
    MySQL安装Write configuration file 提示:configuration file template my.ini Error code-1
    redis批量删除键的操作
    在WINDOWS服务器下设置MARIADB自动备份的方法
    xampp3.2下mysql中文乱码终极解决方案
    CentOS 7虚拟机下模拟实现nginx负载均衡
  • 原文地址:https://www.cnblogs.com/yuyanjiaB/p/10022556.html
Copyright © 2011-2022 走看看