上學路線 遞迴sap 不完全

2022-09-22 23:03:31 字數 3942 閱讀 7084

problem 2 上學路線(route.cpp/c/pas)

【題目描述】

可可和卡卡家住馬賽克市的東郊,每天上學他們都要轉車多次才能到達市區西端的學校。直到有一天他們兩人參加了學校的資訊學奧林匹克競賽小組才發現每天上學的乘車路線不一定是最優的。

馬賽克市一共設有n個公交車站,不妨將它們編號為1…n的自然數,並認為可可和卡卡家住在1號汽車站附近,而他們學校在n號汽車站。市內有m條直達汽車路線,執行第i條路線的公交車往返於站點pi和qi之間,從起點到終點需要花費的時間為ti。(1<=i<=m, 1<=pi, qi<=n)

兩個人坐在電腦前,根據上面的資訊很快就程式設計算出了最優的乘車方案。然而可可忽然有了乙個鬼點子,他想趁卡卡不備,在卡卡的輸入資料中刪去一些路線,從而讓卡卡的程式得出的答案大於實際的最短時間。而對於每一條路線i事實上都有乙個代價ci:刪去路線的ci越大卡卡就越容易發現這個玩笑,可可想知道什麼樣的刪除方案可以達到他的目的而讓被刪除的公交車路線ci之和最小。

馬賽克市的公交網路十分發達,你可以認為任意兩個車站間都可以通過直達或轉車互相到達,當然如果在你提供的刪除方案中,家和學校無法互相到達,那麼則認為上學需要的最短為正無窮大:這顯然是乙個合法的方案。

【輸入格式】

輸入檔案中第一行有兩個正整數n和m,分別表示馬賽克市公交車站和公交汽車路線的個數。以下m行,每行(第i行,總第(i+1)行)用四個正整數(之間由乙個空格隔開)描述第i條路線:pi, qi, ti, ci;具體含義見上文描述。

【輸出格式】

輸出檔案最多有兩行。 第一行中僅有乙個整數,表示從可可和卡卡家到學校需要的最短時間。第二行輸出乙個整數c,表示ci之和

【樣例輸入】

6 71 21 3

2 61 5

1 31 1

3 41 1

4 61 1

5 61 2

1 51 4

【樣例輸出】

【資料範圍】

2<=n<=500,1<=m<=124 750, 1<=ti, ci<=10 000

這題我用的是遞迴sap(),誰知道狂wa。

大家用遞迴sap的時候想必經常會莫名ntr。

結論://dfs_sap()的z正確性目前有待考證。。。

根據我的研究,經驗總結如下:

1.退出條件:

-ps:有可能某次增廣flow=0,但是改距離標號可以繼續flow

-ps:有時候無限增廣,輸答案能看出上面的錯誤

2.修改距離標號:

-ps:距離標號最好直接+1,minj等手段極有可能造成≈沒有距離標號優化的狀況

3.dfs時的flow

-ps:一定要提前return,要不然改距離標號a~

4.重構圖:

-ps:這樣是質的差別,遞迴不卡時間?

5.唯一重點:

ps:實在不行時,去掉距離標號優化!另可t到死,不能wa到爆

6.用遞迴sap唯一的好處是省事……(什麼你1分鐘bfs_sap()?當我沒說)

[cpp]

#include  

#include  

#include  

#include  

#include  

#include  

#define maxn (500+10)  

#define maxm (124750+10)  

#define maxci (10000+10)  

#define inf (2139062143)  

#define for(i,n) for(int i=1;i<=n;i++)  

#define forp(p,u) for (int p=pre[u];p;p=next[p])   

using namespace std; 

int n,m,edge[2*maxm],weight[2*maxm],c[2*maxm],next[2*maxm],pre[maxn],size=1; 

void addedge(int u,int v,int w,int w2) 

int d[maxn],q[maxn*8]; 

void spfa() 

} head++; 

}        

}  int d2[maxn],cnt[maxn]; 

void spfa2() 

} head++; 

}        

}  bool sap_t=1,b[2*maxm]=; 

int sap(int u,int flow) 

else if (c[p]) minj=min(minj,d2[v]); 

} if (--cnt[d2[u]]==0)  

//d2[1]=n+1;     

//  if (minj^inf) cnt[d2[u]=minj+1]++;    

/*  else*/ cnt[++d2[u]]++;   

return tot; 

} int main() 

spfa(); 

//  for (int i=1;i<=n;i++) cout<

cout<

int ans=0; 

spfa2(); 

int de_bug_1=0; 

for(i,n) 

forp(p,i) 

//  cout<

b[0]=1; 

for(i,n) 

forp(p,i) 

while(/*sap_t*/1)  

cout<

return 0; 

} #include

#include

#include

#include

#include

#include

#define maxn (500+10)

#define maxm (124750+10)

#define maxci (10000+10)

#define inf (2139062143)

#define for(i,n) for(int i=1;i<=n;i++)

#define forp(p,u) for (int p=pre[u];p;p=next[p])

using namespace std;

int n,m,edge[2*maxm],weight[2*maxm],c[2*maxm],next[2*maxm],pre[maxn],size=1;

void addedge(int u,int v,int w,int w2)

int d[maxn],q[maxn*8];

void spfa()

}  head++;

}  }int d2[maxn],cnt[maxn];

void spfa2()

}  head++;

}  }bool sap_t=1,b[2*maxm]=;

int sap(int u,int flow)

else if (c[p]) minj=min(minj,d2[v]);

} if (--cnt[d2[u]]==0)

//d2[1]=n+1; 

// if (minj^inf) cnt[d2[u]=minj+1]++; 

/* else*/ cnt[++d2[u]]++; 

return tot;

}int main()

spfa();

// for (int i=1;i<=n;i++) cout<

cout<

int ans=0;

spfa2();

int de_bug_1=0;

for(i,n)

forp(p,i)

// cout<

b[0]=1;

for(i,n)

forp(p,i)

while(/*sap_t*/1)

cout<

return 0;

}

不完全型別

c 允許在乙個 檔案中存放多個類,但這樣往往不便於類的管理,所以一向是提倡乙個檔案中只存放乙個類。不過呢,隨著類規模的不斷膨脹,乙個檔案中存放乙個類也有些顯得臃腫,或者是在某個角度上不便於 的組織。因此,c 2.0中引入了不完全型別的概念,即啟用了新的修飾符partial。借助該修飾符,我們可以在多...

不完全型別

不完全型別指 函式之外 型別的大小不能被確定的型別 總結一下,c的型別分為 結構體的宣告就是乙個不完全型別的典型例子。struct woman tag struct man tag struct woman tag 這樣是沒問題的。如果將man tag結構中的struct woman tag wif...

不完全型別

有時候我們在一些編譯器寫 的時候會碰見不完全型別這個編譯錯誤,那麼什麼是不完全型別,為啥會出現呢 不完全型別指 函式之外 型別的大小不能被確定的型別 只能以有限方式使用。不能定義該型別的物件。不完全型別只能用於定義指向該型別的指標及引用 1 或者用於宣告使用該型別作為形參型別或者返回值型別。c的型別...