• 牛客/科大讯飞杯 L题动物森友会 (二分最大流)


    https://ac.nowcoder.com/acm/problem/205306

    贪心和dp做不了,所以想到这是一个匹配问题。

    建立源点s和汇点t,源点s连接一周的7天,容量为cnt*总天数/7,特判总天数%7有余数的情况。

    一周的7天作为7个节点连接n个task,容量设定为inf。

    n个task连接汇点,容量为m[i]

    由于花费的天数越多,跑出的最大流越大,最大流具有单调性,故可以二分总天数然后重新建图,去跑最大流,判断满流是否等于题目所需,最终找到最少的天数即可。

      1 #include<bits/stdc++.h>
      2 typedef long long ll;
      3 using namespace std;
      4 const int maxn = 1200;
      5 const int inf = 1e9+10;
      6 int tot,s,t,n,cnt,sum;//tot指向空结点,源点s,汇点t
      7 int head[maxn],d[maxn],cur[maxn];//head指向边号
      8 int c[maxn],m[maxn];
      9 int g[maxn][10];
     10 struct edge
     11 {
     12     int next,to;
     13     int cap;
     14 }e[maxn*maxn];
     15 void add(int u,int to,ll w){
     16     e[tot].next = head[u];//边号是tot,head[u]是u节点指向的上一条边
     17     e[tot].to = to;//tot边指向to
     18     e[tot].cap = w;//容量为w
     19     head[u] = tot++;//head[u]变更为tot
     20 }
     21 bool bfs(){//构建层次网络
     22     for(int i = 0;i<=n+10;i++) d[i] = 0,cur[i] = head[i];//初始化深度数组
     23     queue<int> q;
     24     q.push(s);
     25     d[s] = 1;
     26     while(!q.empty()){
     27         int v = q.front();//当前节点v
     28         q.pop();
     29         for (int i = head[v];~i;i = e[i].next)
     30         {
     31             if(!d[e[i].to] && e[i].cap){//如果to节点没访问过,且仍有容量
     32                 d[e[i].to] = d[v] + 1;//深度+1
     33                 q.push(e[i].to);//入队列
     34             }
     35         }
     36     }
     37     return d[t]!=0;//true返回找到增广路
     38 }
     39 int dfs(int end,int u,int Max){//dfs查找所有的增广路并做流量调整
     40     if(u == end || !Max) return Max;//返回找到的流量
     41     int res = 0;
     42     for (int i = cur[u];~i;i = e[i].next)//当前弧优化,从cur[u]这条边开始
     43     {   //遍历cur所连的边,边是e[i]
     44         cur[u] = i;
     45         if(d[e[i].to] == d[u] + 1 && e[i].cap>0){//如果u和to在其中一条增广路上
     46             int t = dfs(end,e[i].to,min(e[i].cap,Max));//递归下去
     47             e[i].cap-= t;//容量减去t
     48             e[i^1].cap+=t;//增加反边容量
     49             Max-=t;//可流入流量减t
     50             res+=t;//最大流+t
     51             if(Max == 0) break;//如果残余流量为0,终止
     52         }
     53     }
     54     return res;//返回
     55 }
     56 int dinic(){
     57     int res = 0;
     58     while(bfs()){//存在增广路 就dfs一遍
     59         res +=dfs(t,s,inf);//寻找s到t的流量
     60     }
     61     return res;
     62 }
     63 bool check(int day){
     64     tot = 0;
     65     memset(head,-1,sizeof(head));
     66     for (int i = 1; i <= 7; ++i)
     67     {
     68         /* code */
     69         if(day%7 >=i){
     70             add(s,i,(day/7)*cnt+cnt);//天数建边
     71             add(i,s,0);
     72         }
     73         else{
     74             add(s,i,(day/7)*cnt);
     75             add(i,s,0);
     76         }
     77     }
     78     for (int i = 1; i <= n; ++i)
     79     {
     80         /* code */
     81         add(i+7,t,c[i]);//task连接汇点t的边,容量为c[i];
     82         add(t,i+7,0);
     83         for(int j = 1;j<=7;j++){
     84             if(g[i][j]) add(j,i+7,inf),add(i+7,j,0);
     85         }
     86   
     87     }
     88     int MaxFlow = dinic();
     89     return MaxFlow >= sum;
     90 }
     91 int main(){
     92     scanf("%d%d",&n,&cnt);
     93     s = 0, t = 7+n+1;
     94     for(int i = 1;i<=n;i++){
     95         scanf("%d%d",&c[i],&m[i]);
     96         sum+=c[i];
     97         int t ;
     98         for(int j = 1;j<=m[i];j++) {scanf("%d",&t);g[i][t] = 1;}
     99     }
    100     int l = 1, r = (sum/cnt+1)*7+100;
    101     int ans = 0;
    102     while(l<=r){
    103         int mid = l+r>>1;
    104         if(check(mid)){//二分总天数
    105             ans = mid;
    106             r = mid - 1;
    107         }
    108         else{
    109             l = mid + 1;
    110         }
    111     }
    112     printf("%d
    ", ans);
    113     return 0;
    114 }
  • 相关阅读:
    关于垂直居中
    linux 前后台程序切换
    mac 下jetbrains IDE系列IDE主题
    mac 安装命令行开发者工具
    python 安装MySQLdb mysql_config not fount
    error: command 'cc' failed with exit status 1
    sqllite 入门
    jieba分词
    zookeeper 故障重连机制
    深入学习 celery
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12733736.html
Copyright © 2020-2023  润新知