zoukankan      html  css  js  c++  java
  • bzoj1570: [JSOI2008]Blue Mary的旅行

    二分答案+最大流。最大流建分层图就可以了。一开始傻叉把r=n*T。然后要注意以后一定要注意数据范围啊啊啊

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define REP(i,s,t) for(int i=s;i<=t;i++)
    #define op() clr(head,0);pt=edges;
    #define qwq(x) for(edge *o=head[x];o;o=o->next)
    int read(){
    	int x=0;char c=getchar();bool f=true;
    	while(!isdigit(c)) {
    		if(c=='-') f=false;c=getchar();
    	}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    const int nmax=5005;
    const int inf=0x7f7f7f7f;
    struct edge{
    	int to,cap;edge *next,*rev;
    };
    edge edges[100000],*pt,*head[nmax],*cur[nmax],*p[nmax];
    int cnt[nmax],h[nmax],g[55][55],n,m,T;
    void add(int u,int v,int d){
    	pt->to=v;pt->cap=d;pt->next=head[u];head[u]=pt++;
    }
    void adde(int u,int v,int d){
    	add(u,v,d);add(v,u,0);head[u]->rev=head[v];head[v]->rev=head[u];
    }
    void init(){
    	op();clr(g,0);
    	n=read(),m=read(),T=read();
    	rep(i,m) {
    		int u=read(),v=read(),d=read();g[u][v]=d;
    	}
    }
    int maxflow(int s,int t,int n){
    	clr(cnt,0);clr(h,0);cnt[0]=n;
    	int flow=0,a=inf,x=s;edge *e;
    	while(h[s]<n){
    		for(e=cur[x];e;e=e->next) if(e->cap>0&&h[x]==h[e->to]+1) break;
    		if(e){
    			a=min(a,e->cap);p[e->to]=cur[x]=e;x=e->to;
    			if(x==t){
    				while(x!=s) p[x]->cap-=a,p[x]->rev->cap+=a,x=p[x]->rev->to;
    				flow+=a,a=inf;
    			}
    		}else{
    			if(!--cnt[h[x]]) break;
    			h[x]=n;
    			for(e=head[x];e;e=e->next) if(e->cap>0&&h[x]>h[e->to]+1) h[x]=h[e->to]+1,cur[x]=e;
    			cnt[h[x]]++;
    			if(x!=s) x=p[x]->rev->to;
    		}
    	}
    	return flow;
    }
    int check(int x){
    	int s=0,t=(x+1)*n+1;op();
    	adde(s,1,T);
    	rep(i,x){
    		rep(j,n) rep(k,n) if(g[j][k]) adde((i-1)*n+j,i*n+k,g[j][k]);
    		rep(j,n-1) adde((i-1)*n+j,i*n+j,inf);
    		adde(i*n,t,inf);
    	}
    	adde((x+1)*n,t,inf);
    	return maxflow(s,t,t+1);
    }
    void work(){
    	int l=1,r=n+T,ans;
    	while(l<=r){
    		int mid=(l+r)>>1;
    		if(check(mid)==T) ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	printf("%d
    ",ans);
    }
    int main(){
    	init();work();
    	return 0;
    }
    

      

    1570: [JSOI2008]Blue Mary的旅行

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 381  Solved: 206
    [Submit][Status][Discuss]

    Description

    在一段时间之后,网络公司终于有了一定的知名度,也开始收到一些订单,其中最大的一宗来自B市。Blue Mary决定亲自去签下这份订单。为了节省旅行经费,他的某个金融顾问建议只购买U航空公司的机票。U航空公司的所有航班每天都只有一班,并且都是上午出发当天下午到达的,所以他们每人每天只能坐一班飞机。经过调查,他们得到了U航空公司经营的所有航班的详细信息,这包括每一航班的出发地,目的地以及最多能买到的某一天出发的票数。(注意: 对于一个确定的航班,无论是哪一天,他们最多能买到的那一天出发的票数都是相同的。) Blue Mary注意到他们一定可以只乘坐U航空公司的航班就从A市到达B市,但是,由于每一航班能买到的票的数量的限制,他们所有人可能不能在同一天到达B市。所以现在Blue Mary需要你的帮助,设计一个旅行方案使得最后到达B市的人的到达时间最早。

    Input

    第一行包含3个正整数N,M和T。题目中会出现的所有城市分别编号为1,2,…,N,其中城市A编号一定为1,城市B编号一定为N. U公司一共有M条(单向)航班。而连Blue Mary在内,公司一共有T个人要从A市前往B市。 以下M行,每行包含3个正整数X,Y,Z, 表示U公司的每一条航班的出发地,目的地以及Blue Mary最多能够买到的这一航班某一天出发的票数。(即:无论是哪一天,Blue Mary最多只能买到Z张U航空公司的从城市X出发到城市Y的机票。) 输入保证从一个城市到另一个城市的单向航班最多只有一个。

    Output

    仅有一行,包含一个正整数,表示最后到达B市的人的最早到达时间。假设他们第一次乘飞机的那一天是第一天。

    Sample Input

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

    Sample Output

    6

    HINT

    约定:
    2 <= N <= 50
    1 <= M <= 2450
    1 <= T <= 50
    1 <= X,Y <= N
    X != Y
    1 <= Z <= 50

    Source

     
    [Submit][Status][Discuss]
  • 相关阅读:
    设计模式 — 责任链模式
    BlockingQueue 阻塞队列(生产/消费者队列)
    DDD工作流持久化(十六)
    js中匿名函数和回调函数
    DDD模型领域WF到领域层(十五)
    DDD领域模型系统的工作流(十四)
    DDD领域模型数据访问权限之权限(十二)
    DDD领域模型数据访问之对象(十一)
    DDD领域模型数据访问权限之用户权限(十)
    DDD领域模型数据访问权限(九)
  • 原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5678013.html
Copyright © 2011-2022 走看看