codevs 1227 方格取數2(費用流)

2021-07-23 02:50:56 字數 1863 閱讀 8390

時間限制: 1 s 空間限制: 128000 kb題目等級 : 大師master

題目描述 description

給出乙個n*n的矩陣,每一格有乙個非負整數aij,(aij <= 1000)現在從(1,1)出發,可以往右或者往下走,最後到達(n,n),每達到一格,把該格仔的數取出來,該格仔的數就變成0,這樣一共走k次,現在要求k次所達到的方格的數的和最大

輸入描述 input description

第一行兩個數n,k(1<=n<=50, 0<=k<=10)

接下來n行,每行n個數,分別表示矩陣的每個格仔的數

輸出描述 output description

乙個數,為最大和

樣例輸入 sample input

3 1

1 2 3

0 2 1

1 4 2

樣例輸出 sample output

11

資料範圍及提示 data size & hint

1<=n<=50, 0<=k<=10

【題解】【網路流費用流】

【建圖:拆點,將乙個點拆成兩個,兩點之間連兩條邊,一條邊流量為1,權值為方格裡的數(表示每個數只能取一次);另一條邊流量為走的次數k,權值為0(即每個方格可以走多次,但數只能取一次)。 然後再加上源點和匯點,源點到(1,1)的邊的流量為k,權值為0;(n,n)到匯點的邊的流量為k,權值為0】

【要考慮dis陣列的初值應賦為極小值,再逐漸向大更新】

#include#include#include#includeusing namespace std;

int a[50100],next[50100],p[5010],remain[50100],w[50100],tot=-1;

int dis[50100],last[50100];

int n,k,maxflow,mincost,n1,tt;

bool b[50100];

inline void add(int x,int y,int z,int cost)

inline int addflow(int s,int t)

now=t;

while (now!=s)

return sum;

}inline bool spfa(int s,int t)

{ int x;

memset(dis,128,sizeof(dis));

memset(b,true,sizeof(b));

queueque; x=dis[0];

b[s]=false; dis[s]=0; que.push(s);

while (!que.empty())

{int u,v;

u=que.front(); que.pop();

v=p[u]; b[u]=true;

while (v!=-1)

{if (remain[v]&&dis[a[v]]

codevs 1227 方格取數2

網路流 拆點 好像hdu上有類似的題。那時我還是用pascal寫的 算是裸題吧。然而我本不會費用流 看了下黃學長的 說下自己的理解 黃學長只貼了 把每乙個點拆成兩個點,乙個是流進的,乙個是流出的 然後建邊。這兩個點之間有這幾類邊 由流入點指向流出點,流量為1,費用為map i,j 由流出點指向流入點...

code vs 1227 方格取數 2

時間限制 1 s 空間限制 128000 kb 題目等級 大師 master 題解 檢視執行結果 給出乙個n n的矩陣,每一格有乙個非負整數aij,aij 1000 現在從 1,1 出發,可以往右或者往下走,最後到達 n,n 每達到一格,把該格仔的數取出來,該格仔的數就變成0,這樣一共走k次,現在要...

codevs1227 方格取數 2

題目鏈結 n n的方格,每個格仔中有乙個數,尋找從 1,1 走到 n,n 的k條路徑,使得取到的數的和最大。經典的費用流應用吧。額外新增源點s和匯點t,分別與 1,1 和 n,n 連邊。把棋盤中每個點拆成兩個,連兩條弧。其中一條容量為1,費用為該點的數字大小 另一條容量為inf,費用為0。這就表示乙...