安徽上學路線

2021-09-10 21:22:09 字數 1452 閱讀 9881

思路:跑spfa+網路流最小割。跑正反兩邊spfa,然後拎出一條邊,判斷邊權+左端點到1號節點的最短路+右端點到n號節點的最短路(離1號節點近的點為左端點,反之為右端點)是否等於1到n的最短路,如果相等左右端點連邊,權值為這條邊代價。然後跑dinic。

【分析】真是桑心!!這道題切了乙個晚上,最後在rc(red cow)的幫助下才解決的。

第一問直接是最短路啊。第二問的意思我看了好久——要選擇刪掉一些路,使起點到終點的最短路並不是原來的最短路(就是稍微大一些,哪怕大1也可以),同時使刪掉的路的ci之和最小。

這樣就很好做了,直接把原來在最短路上的邊全部拎出來,做一遍最小割(因為可能有多條最短路)。

【注意點】信心滿滿地交上去,一直是wa!恰好這一年沒有資料,我只能死磕了。自己造了幾個資料全部正確!於是無奈地網上下了個標程,寫make_data對拍。

拍了5分鐘有乙個錯誤:我的q佇列開小了。在做spfa的時候,即使用了flag陣列記錄是否在佇列中,q陣列也必須要開大!!(除非用迴圈佇列)rc說spfa操作的佇列最保險的應該開邊的10倍。

後來就一直沒拍出錯誤,可是交上去還是wa!盯著螢幕半天,仍然沒什麼發現!最後,rc一瞪眼:是不是有重邊?我馬上把我的鄰接矩陣上加了個+,結果a了。恰好我造的資料時去重的,怪不得拍不出錯誤。

歸納兩點:spfa佇列要開大;注意重邊。

#include#include#include#include#define inf 2100000000

using namespace std;

struct arr

e[250005];

int mm[1005][1005],d[2][1005],f1[1005],

h[1005],x,y,z,c,i,j,n,m,t,ans;

bool f[1005];

queueq;

void add(int u,int v,int s,int w)

void spfa(int x,int y)}}

f[k]=0;

}}bool bfs()

}return 0;

}int dinic(int x,int y)

if (yy==y)

f1[x]=-1;

return y-yy;

}int main()

memset(d,0x3f,sizeof(d));

spfa(0,1);

spfa(1,n);

for (i=1; i<=n; i++)

for (j=h[i]; j; j=e[j].n)

if (d[0][i]+e[j].s+d[1][e[j].t]==d[0][n])

mm[i][e[j].t]+=e[j].c;

while (bfs())

ans+=dinic(1,inf);

printf("%d\n%d\n",d[0][n],ans);

}

2693 上學路線(施工)

題目描述 description 問題描述 你所在的城市街道好像乙個棋盤,有a條南北方向的街道和b條東西方向的街道。南北方向a條街道從西到東依次編號為1到a,而東西方向的b條街道從南到北依次編號為1到b,南北方向的街道i和東西方向的街道j的交點記為 i,j 假定你住在 1,1 處,而學校在 a,b ...

計蒜客 上學路線

你所在城市的街道好像乙個棋盤,有 a 條南北方向的街道和 b條東西方向的街道。南北方向的 a 條街道從西到東依次編號為 l 到 a,而東西方向的 b 條街道從南到北依次編號為 l 到 b,南北方向的街道 i 和東西方向的街道 j 的交點記為 i,j 你住在 1,1 處,而學校在 a,b 處,你騎自行...

BZOJ3782 上學路線

bzoj 第一行,四個整數 n,m,t,p 接下來的 t 行,每行兩個整數,表示施工的路口的座標。一行,乙個整數,路徑數 mod p 的值。3 4 3 1019663265 3 01 1 2 28 1 le n,m le 10 0 le t le 200 p 1000003 或 p 10196632...