作為乙個旅行達人以及航空公司的金卡會員,你每一年的飛行里程可以繞赤道幾周了。你發現,航空公司為了提高飛機的使用率,並不是簡單的一條航線使用一架飛機來回飛,而是會讓同一架飛機連續不停地飛不同的航線,甚至有的時候為了能夠完成飛機的排程,航空公司還會增開一些臨時航線——在飛機轉場的同時順路捎一些乘客。你研究了一下gdoi著名航空公司gd airways的常規直飛航線,你想知道,在最佳排程方案下,gd airways最少需要多少架飛機才能成功執飛這所有的航線。
gdoi王國裡有n個機場,編號為1到n。從i號機場到j號機場需要飛行ti,j的時間。由於風向,地理位置和航空管制的因素,ti,j和tj,i並不一定相同。
此外,由於飛機降落之後需要例行維修和加油。當一架飛機降落k號機場時,需要花費pk的維護時間才能再次起飛。
gd airways一共運營m條航線,其中第i條直飛航線需要在di時刻從xi機場起飛,不經停,飛往yi機場。
為了簡化問題,我們假設gd airways可以在0時刻在任意機場任意多架加油維護完畢的飛機;為了減少飛機的使用數,我們允許gd airways增開任意多條臨時航線以滿足飛機的排程需要。
你想知道,理論上gd airways最少需要多少架飛機才能完成所有這m個航班。
從檔案flight.in中讀入資料。
輸入一行包含兩個正整數n和m。
接下來一行包含n個正整數表示每乙個機場的飛機維護時間。
接下來n行,每行n個非負整數,其中第i行第j個非負整數為ti,j,表示從第i號機場飛往j號機場所需要花費的時間。資料保證ti,i=0。
接下來m行,每行3個正整數,其中第i行為xi,yi,di,表示第i條航線的起飛機場,降落機場,以及起飛時間。資料保證xi≠yi。
輸出到檔案flight.out中。
輸出檔案包含一行乙個正整數,表示gd airways理論上最少需要的飛機數。
樣例輸入1:
3 3
100 1 1
0 1 1
1 0 5
2 1 0
1 2 1
2 1 1
3 1 9
樣例輸入2:
3 3
100 1 1
0 1 1
1 0 5
2 1 0
1 2 1
2 1 1
3 1 8
樣例輸出1:
2 樣例輸出2:
3對於30%的資料滿足n,m<=10;
對於60%的資料滿足n,m<=100;
對於100%的資料滿足1<=n,m<=500,0<=pi,ti,j<=106,1<=di<=106。
在第乙個樣例中,gd airways可以在0時刻在2號機場安排一架飛機並執飛第2條航線(2–>1)。此外還需要在0時刻在1號機場安排一架飛機,這架飛機首先執飛第1條航線(1–>2),然後通過臨時新增一條航線從2號機場起飛飛往3號機場,降落3號機場之後執飛第3條航線(3–>1)。
在第二個樣例中,執行完第1條航線的飛機無法趕上第3條航線的起飛時間,因此gd airways必須使用3架不同的飛機才能完成所有的航班。
這題看很神奇。
首先我想到了dp。仔細想一想,發現根本無法推出狀態轉移方程。
接著我想到了網路流,然後發現……
由題意可知,如果乙個航班飛完了這個航線,要飛下一條航線,必須要在那班航班開始前到大那個機場並加油完。也就是說飛機不能晚點。
那麼一架飛機飛完一條航線後到達下乙個航線的起點位置不需要直飛,就用乙個floyd求出最短路。然而飛機到達機場需要修理,可以吧修理的時間算在路線長度內,就不需要再判斷了。
如果乙個航線的終點ti飛到另乙個航線的起點sj,並且可以再時間內的話,就把i與j連邊。那麼要使所需飛機最少,就是要在圖中求最小路徑覆蓋。
最小路徑覆蓋用二分圖匹配就行了。(匈牙利演算法)
注意:飛航線必須直飛,而從乙個終點飛到另乙個起點要最短路。
#include
#include
#include
#include
#include
#define n 510
#define max 21474836
#define fo(i,a,b) for(int i=a;i<=b;i++)
intmap[n][n],a[n][n],p[n],h[n],n,m,last[n],next[n*1000],to[n*1000],b[n],tot=0,st,bz[n];
struct note
;note f[n];
using namespace std;
void putin(int
x,int
y)bool dg(int
x) }
return0;}
int main()
fo(i,1,m) scanf("%d
%d%d",&f[i].s,&f[i].t,&f[i].d);
fo(k,1,n)
fo(i,1,n)
fo(j,1,n)
if (i!=j && a[i][j]>a[i][k]+a[k][j])
fo(i,1,m)
fo(j,1,m)
if (i!=j && f[i].d+map[f[i].s][f[i].t]+a[f[i].t][f[j].s]<=f[j].d)
int ans=m;
for(st=1;st<=m;st++) if (dg(st)) ans--;
printf("%d",ans);
fclose(stdin);fclose(stdout);
}
GDOI2016模擬8 8旋轉
alice和bob發明了乙個新的旋轉遊戲。首先,bob給定n個數組成的序列,並把該序列平均分配成若干個塊,每塊正好包含k個數 k能整除n 第一塊由第1到第k個數構成,第二塊由第k 1個數到第2k個數構成,以此類推。接著,bob要求alice對這個序列進行一系列操作,操作有以下兩種 1.把每塊裡面的數...
GDOI2016模擬8 13總結
這次考差了。但事後想了一下,感覺收穫好大。匯報做題情況 當然,裡面不包含收穫 第一題 我的暴力爆零了,原因又是爆int 做題過程中我想到了與眾不同的演算法,一般人會化簡不等式變成斜率優化做,但由於我對斜率優化不大敏感,而且一般斜率優化的題目都是用凸包 叉積來做,這題我也同樣想著用凸包做,但打完發現有...
GDOI2016模擬8 16幫派
農場裡的生活很艱苦,而且當生活很艱苦,你必須堅強起來。奶牛們形成了編號為1到m的幫派。這些幫派一開始和睦相處了一段時間,但是現在失控了!奶牛們在競爭一片大草地的控制權。奶牛之間的衝突發生在連續的若干分鐘內。每一分鐘有乙隻奶牛走進草地。如果此時草地上沒有奶牛,那麼這只新進去的奶牛所在的幫派就能占領這片...