【bzoj1570】[JSOI2008]Blue Mary的旅行 動態加邊網路流

來源:互聯網
上載者:User

標籤:sample   eof   pos   個人   拆點   led   inf   soft   包含   

題目描述

在一段時間之後,網路公司終於有了一定的知名度,也開始收到一些訂單,其中最大的一宗來自B市。Blue Mary決定親自去簽下這份訂單。為了節省旅行經費,他的某個金融顧問建議只購買U航空公司的機票。U航空公司的所有航班每天都只有一班,並且都是上午出發當天下午到達的,所以他們每人每天只能坐一班飛機。經過調查,他們得到了U航空公司經營的所有航班的詳細資料,這包括每一航班的出發地,目的地以及最多能買到的某一天出發的票數。(注意: 對於一個確定的航班,無論是哪一天,他們最多能買到的那一天出發的票數都是相同的。) Blue Mary注意到他們一定可以只乘坐U航空公司的航班就從A市到達B市,但是,由於每一航班能買到的票的數量的限制,他們所有人可能不能在同一天到達B市。所以現在Blue Mary需要你的協助,設計一個旅行方案使得最後到達B市的人的到達時間最早。

輸入

第一行包含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的機票。) 輸入保證從一個城市到另一個城市的單向航班最多隻有一個。

輸出

僅有一行,包含一個正整數,表示最後到達B市的人的最早到達時間。假設他們第一次乘飛機的那一天是第一天。

範例輸入

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

範例輸出

6

題解

動態加邊網路流

由於題目中限定一人每天只能坐一次飛機,所以可以將飛機的已耗用時間看作一天,出發時間看作第0天。

這樣就可以拆點,將每個除1和n以外的點拆成totaltime+1個,看作0~totaltime+1層。注意點1和點n不需要拆,即1和n無論在多少層,編號始終為1和n。

首先加S->1,容量為T,代表T個人。

然後枚舉時間t,設點x在第k層所拆的點為(x,k),則加邊(i,t-1)->(i,t),容量為inf;對於原圖中的邊x->y(z),加邊(x,t-1)->(y,t),容量為z。

這樣動態加邊後把n看做匯點,跑dinic,判斷一下是否滿流即可。

#include <cstdio>#include <cstring>#include <queue>#define N 10010#define M 1000010#define inf 0x3f3f3f3f#define pos(i , j) (i == 1 || i == n) ? i : (n - 2) * (j) + i + 1using namespace std;queue<int> q;int head[N] , to[M] , val[M] , next[M] , cnt = 1 , s , t , dis[N] , dx[M] , dy[M] , dz[M];void add(int x , int y , int z){to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;to[++cnt] = x , val[cnt] = 0 , next[cnt] = head[y] , head[y] = cnt;}bool bfs(){int x , i;memset(dis , 0 , sizeof(dis));while(!q.empty()) q.pop();dis[s] = 1 , q.push(s);while(!q.empty()){x = q.front() , q.pop();for(i = head[x] ; i ; i = next[i]){if(val[i] && !dis[to[i]]){dis[to[i]] = dis[x] + 1;if(to[i] == t) return 1;q.push(to[i]);}}}return 0;}int dinic(int x , int low){if(x == t) return low;int temp = low , i , k;for(i = head[x] ; i ; i = next[i]){if(val[i] && dis[to[i]] == dis[x] + 1){k = dinic(to[i] , min(temp , val[i]));if(!k) dis[to[i]] = 0;val[i] -= k , val[i ^ 1] += k;if(!(temp -= k)) break;}}return low - temp;}int main(){int n , m , k , i , j , ans = 0;scanf("%d%d%d" , &n , &m , &k);s = 0 , t = n , add(s , 1 , k);for(i = 1 ; i <= m ; i ++ ) scanf("%d%d%d" , &dx[i] , &dy[i] , &dz[i]);for(i = 1 ; i <= n + k ; i ++ ){for(j = 2 ; j < n ; j ++ ) add(pos(j , i - 1) , pos(j , i) , inf);for(j = 1 ; j <= m ; j ++ ) add(pos(dx[j] , i - 1) , pos(dy[j] , i) , dz[j]);while(bfs()) ans += dinic(s , inf);if(ans == k){printf("%d\n" , i);return 0;}}return 0;}

 

【bzoj1570】[JSOI2008]Blue Mary的旅行 動態加邊網路流

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.