Less Time, More profit

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Problem Description
The city planners plan to build N plants in the city which has M shops.

Each shop needs products from some plants to make profit of i).

You should make a plan to make profit of at least L units in the shortest period.
 
Input
First line contains T, a number of test cases.

For each test case, there are three integers N, M, L described above.

And there are N lines and each line contains two integers 30000
 

 Output

For each test case, first line contains a line “Case #x: t p”, x is the number of the case, t is the shortest period and p is maximum profit in t hours. You should minimize t first and then maximize p.

If this plan is impossible, you should print “Case #x: impossible”
 

Sample Input

2
1 1 2
1 5
3 1 1
 
1 1 3
1 5
3 1 1
 

Sample Output

Case #1: 5 2
Case #2: impossible
 

 Author

金策工业综合大学(DPRK)
  
Source

 M个商店,N个工厂,每个商店获利的条件是建设了指定的k个工厂。求总获利不小于L,工厂建设的时间最大值最小是多少。

 工厂到汇点建一条边pay[i],源点到商店建一条边pro[i],商店到需要的工厂建一条边INF,商店的总收益-最小割就是答案。

可以看看国家集训队论文:Amber《最小割模型在信息学竞赛中的应用》

 

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#define N 205<<1
#define sf(a) scanf("%d",&a);
using namespace std;
const int INF=0x3f3f3f3f;
struct plant{
    int pay,t,id;
}pt[N];
struct shop{
    int pro,k,pt[N],t;
}s[N];
int t,n,m,l,st,ed,tot;
int arc[N][N], d[N];
int ans,tans;
bool bfs()
{
    memset(d, -1, sizeof d);
    queue<int>q;
    q.push(st);
    d[st] = 0;
    while(!q.empty())
    {
        int i,k=q.front();
        q.pop();
        for(i = 1; i <= ed; i++)
            if(arc[k][i] > 0 && d[i] == -1)
            {
                d[i] = d[k] + 1;
                q.push(i);
            }
    }
    return d[ed]>0;
}
int dinic (int k, int low)
{
    if(k == ed)return low;
    int a,i;
    for(i = 1; i <= ed; i++)
        if(d[i] == d[k] + 1&&  arc[k][i] > 0 &&(a = dinic(i, min(low, arc[k][i]))))
        {
            arc[k][i] -= a;
            arc[i][k] += a;
            return a;
        }
    return 0;
}
int cmp(plant a,plant b){
    return a.t<b.t;
}
int main() {
    sf(t);
    for(int cas=1;cas<=t;cas++){
        printf("Case #%d: ",cas);
        scanf("%d%d%d",&n,&m,&l);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&pt[i].pay,&pt[i].t);
            pt[i].id=i;
        }
        for(int i=1;i<=m;i++){
            sf(s[i].pro);
            sf(s[i].k);
            s[i].t=0;
            for(int j=1;j<=s[i].k;j++){
                int x;
                sf(x);
                s[i].pt[j]=x;
                s[i].t=max(s[i].t,pt[x].t);
            }
        }
        sort(pt+1,pt+1+n,cmp);
        int ok=0;
        st=n+m+1,ed=st+1;
        for(int i=1;i<=n;i++){
            memset(arc,0,sizeof arc);
            for(int j=1;j<=i;j++)
                arc[pt[j].id][ed]=pt[j].pay;
            tot=0;
            for(int j=1;j<=m;j++)if(s[j].t<=pt[i].t){
                tot+=s[j].pro;
                arc[st][j+n]=s[j].pro;
                for(int k=1;k<=s[j].k;k++)
                arc[j+n][s[j].pt[k]]=INF;
            }
            ans = 0;
            while(bfs())
                while(tans=dinic(st, INF)) ans += tans;
            ans=tot-ans;
            if(ans>=l){
                printf("%d %d\n",pt[i].t,ans);
                ok=1;
                break;
            }
        }
        if(!ok)puts("impossible");
    }
}

 

工厂按时间排序再依次增大最大时间,这样是140ms,改成二分以为会更快,结果960ms,去了注释们再交一次居然超时了。可能是dinic用的是邻接矩阵的原因。

相关文章:

  • 2021-09-13
  • 2021-06-17
  • 2021-09-01
  • 2022-01-03
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-02-11
  • 2022-02-24
  • 2021-11-09
  • 2021-07-16
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案