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
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
正解:最大流。
最大流+按时间拆点的裸套路。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 #define N (2000010) 6 #define inf (1<<30) 7 ?8 using namespace std; 9 10 struct edge{ int nt,to,flow,cap; }g[N];11 struct e{ int u,v,w; }e[2500];12 13 int id[52][310],head[N],q[N],d[N],S,T,n,m,t,num,cnt,ans,flow;14 15 il int gi(){16 ??RG int x=0,q=1; RG char ch=getchar();17 ??while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar();18 ??if (ch==‘-‘) q=-1,ch=getchar();19 ??while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar();20 ??return q*x;21 }22 23 il void insert(RG int from,RG int to,RG int cap){24 ??g[++num]=(edge){head[from],to,0,cap},head[from]=num;25 ??g[++num]=(edge){head[to],from,0,0},head[to]=num; return;26 }27 28 il int bfs(RG int S,RG int T){29 ??for (RG int i=1;i<=cnt;++i) d[i]=0;30 ??RG int h=0,t=1; q[t]=S,d[S]=1;31 ??while (h<t){32 ????RG int x=q[++h],v;33 ????for (RG int i=head[x];i;i=g[i].nt){34 ??????v=g[i].to;35 ??????if (!d[v] && g[i].cap>g[i].flow){36 ????d[v]=d[x]+1,q[++t]=v;37 ????if (v==T) return 1;38 ??????}39 ????}40 ??}41 ??return d[T];42 }43 44 il int dfs(RG int x,RG int T,RG int a){45 ??if (!a || x==T) return a; RG int v,f,flow=0;46 ??for (RG int i=head[x];i;i=g[i].nt){47 ????v=g[i].to;48 ????if (d[v]==d[x]+1 && g[i].cap>g[i].flow){49 ??????f=dfs(v,T,min(a,g[i].cap-g[i].flow));50 ??????if (!f){ d[v]=-1; continue; }51 ??????g[i].flow+=f,g[i^1].flow-=f;52 ??????flow+=f,a-=f; if (!a) return flow;53 ????}54 ??}55 ??return flow;56 }57 58 il int maxflow(RG int S,RG int T){59 ??RG int flow=0;60 ??while (bfs(S,T)) flow+=dfs(S,T,inf);61 ??return flow;62 }63 64 int main(){65 #ifndef ONLINE_JUDGE66 ??freopen("bluemary.in","r",stdin);67 ??freopen("bluemary.out","w",stdout);68 #endif69 ??n=gi(),m=gi(),t=gi(),num=1,S=++cnt,T=++cnt;70 ??for (RG int i=1;i<=m;++i) e[i].u=gi(),e[i].v=gi(),e[i].w=gi();71 ??for (RG int i=1;i<=n;++i) id[i][0]=++cnt;72 ??insert(S,id[1][0],t),insert(id[n][0],T,inf);73 ??while (++ans){74 ????for (RG int i=1;i<=n;++i) id[i][ans]=++cnt,insert(id[i][ans-1],id[i][ans],inf);75 ????for (RG int i=1;i<=m;++i) insert(id[e[i].u][ans-1],id[e[i].v][ans],e[i].w);76 ????insert(id[n][ans],T,inf),flow+=maxflow(S,T); if (flow==t) break;77 ??}78 ??cout<<ans; return 0;79 }
bzoj1570 [JSOI2008]Blue Mary的旅行
原文地址:http://www.cnblogs.com/wfj2048/p/7655402.html