codeforces 589F Gourmet and Banquet

不知道写的是什么qwq
F. Gourmet and Banquet
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output

A gourmet came into the banquet hall, where the cooks suggested n dishes for guests. The gourmet knows the schedule: when each of the dishes will be served.

For i-th of the dishes he knows two integer moments in time ai and bi (in seconds from the beginning of the banquet) — when the cooks will bring the i-th dish into the hall and when they will carry it out (ai < bi). For example, if ai = 10 and bi = 11, then the i-th dish is available for eating during one second.

The dishes come in very large quantities, so it is guaranteed that as long as the dish is available for eating (i. e. while it is in the hall) it cannot run out.

The gourmet wants to try each of the n dishes and not to offend any of the cooks. Because of that the gourmet wants to eat each of the dishes for the same amount of time. During eating the gourmet can instantly switch between the dishes. Switching between dishes is allowed for him only at integer moments in time. The gourmet can eat no more than one dish simultaneously. It is allowed to return to a dish after eating any other dishes.

The gourmet wants to eat as long as possible on the banquet without violating any conditions described above. Can you help him and find out the maximum total time he can eat the dishes on the banquet?
Input

The first line of input contains an integer n (1 ≤ n ≤ 100) — the number of dishes on the banquet.

The following n lines contain information about availability of the dishes. The i-th line contains two integers ai and bi (0 ≤ ai < bi ≤ 10000) — the moments in time when the i-th dish becomes available for eating and when the i-th dish is taken away from the hall.
Output

Output should contain the only integer — the maximum total time the gourmet can eat the dishes on the banquet.

The gourmet can instantly switch between the dishes but only at integer moments in time. It is allowed to return to a dish after eating any other dishes. Also in every moment in time he can eat no more than one dish.
Examples
Input

3
2 4
1 5
6 9

Output

6

Input

3
1 2
1 2
1 2

Output

0

Note

In the first example the gourmet eats the second dish for one second (from the moment in time 1 to the moment in time 2), then he eats the first dish for two seconds (from 2 to 4), then he returns to the second dish for one second (from 4 to 5). After that he eats the third dish for two seconds (from 6 to 8).

In the second example the gourmet cannot eat each dish for at least one second because there are three dishes but they are available for only one second (from 1 to 2).

自己想了个想法 大概就是和现在的类似只不过 不是每个点 而是每段的去划分 然后边权是这段的长度 但是要重标号什么的比较麻烦 借鉴了下icefox大佬的做法 确实因为最多只有100个点 然后时间段也只有10000个时间段 所以直接以每个时间段去划分即可我的改进方法就是源向每道菜建边 然后每个菜再向时间点建边 注意这个时间可能2~3的区间只可以有1s的吃的时间我是建成了左开右闭的区间 然后每个 时间点再向汇建边 每次二分我每个人能有多少的时间吃每道菜 然后去判断一下是否满流 然后一直贰分下去即可


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 11000
#define inf 0x3f3f3f3f 
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0;char ch=gc();
    while(ch<'0'||ch>'9') ch=gc();
    while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}
    return x;
}
int num=1,h[N],level[N],n,st,T;
struct node{
    int x,y,z,next;
}data[2200000];
inline void insert1(int x,int y,int z){
    data[++num].y=y;data[num].z=z;data[num].next=h[x];h[x]=num;data[num].x=x;
    data[++num].y=x;data[num].z=0;data[num].next=h[y];h[y]=num;data[num].x=y;
}
inline bool bfs(){
    memset(level,0,sizeof(level));queue<int>q;q.push(0);level[0]=1;
    while(!q.empty()){
        int x=q.front();q.pop();
        for (int i=h[x];i;i=data[i].next){
            int y=data[i].y,z=data[i].z;
            if(level[y]||!z) continue;level[y]=level[x]+1;q.push(y);if (y==T) return 1;
        }
    }return 0;
}
inline int dfs(int x,int s){
    if (x==T) return s;int ss=s;
    for (int i=h[x];i;i=data[i].next){
        int y=data[i].y,z=data[i].z;
        if(level[x]+1==level[y]&&z){
            int xx=dfs(y,min(s,z));if (!xx) level[y]=0;
            s-=xx;data[i].z-=xx;data[i^1].z+=xx;if (!s) return ss;
        }
    }return ss-s;
}
inline bool check(int x){
    for (int i=st;i<=num;++i) if ((i&1)==0) data[i].z=x;else data[i].z=0;
    for (int i=2;i<st;++i) if ((i&1)==0) data[i].z=1;else data[i].z=0;
    int ans=0;while(bfs()) ans+=dfs(0,inf);bool flag=1;
//  printf("%d",x);printf("asdfas\n");
    for (int i=h[0];i;i=data[i].next){
        int y=data[i].y;
        if (y>=10001&&y<=10000+n) if (data[i].z!=0) flag=0;
    }
    //for (int i=2;i<=num;++i) printf("%d %d %d\n",data[i].x,data[i].y,data[i].z);printf("fdasdf\n");
    return flag;
    //if(ans==n*x) return 1;else return 0;
}
int main(){
    freopen("cf.in","r",stdin); 
    n=read();int sum=0;T=10000+n+1;int max1=0;
    for (int i=1;i<=n;++i){
        int l=read(),r=read();sum+=r-l+1;max1=max(max1,r);
        for (int j=l+1;j<=r;++j) insert1(10000+i,j,1);
    }for (int i=1;i<=max1;++i) insert1(i,T,1);st=num+1;
    for (int i=1;i<=n;++i) insert1(0,10000+i,1);
    int l=0,r=sum/n;//printf("%d %d\n",l,r);
    while(l<=r){
        int mid=l+r>>1;
        if (check(mid)) l=mid+1;else r=mid-1;
    }printf("%d",r*n);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值