在乙個\(n*n\)的矩形網格中,每個格仔裡都寫著乙個非負整數。
可以從左上角到右下角安排\(k\)條路線,每一步只能往下或往右,沿途經過的格仔中的整數會被取走。
若多條路線重複經過乙個格仔,只取一次。求能取得的整數的和最大是多少。
這道題與數字梯形那道題的第三問很像,區別在於數字梯形是\(m\)個起點,若干個終點,每個數字可以取無限次。這道題是\(1\)個起點,\(1\)個終點,每個數字只能取\(1\)次,但是可以到達無限次。
起點和終點的問題很好處理,關鍵在於如何處理每個數字只能取\(1\)次,但是可以到達無限次的情況呢。
這裡有個技巧就是,入點向出點連兩條邊,一條邊的容量是\(1\),費用是點權;另一條邊的容量是\(k - 1\),費用是\(0\)。
其他建圖方式與數字梯形那道題相同,即每個點向右和下兩個點連容量是\(k\),費用是\(0\)的邊。源點向起點連容量是\(k\),費用是\(0\)的邊;終點向匯點連容量是\(k\),費用是\(0\)的邊。
跑最大費用流即可。
#include #include #include #include #include using namespace std;
const int n = 5010, m = 20010, inf = 1e8;
int n, k, s, t;
int h[n], e[m], ne[m], f[m], w[m], idx;
int pre[n], d[n], incf[n];
bool st[n];
int cost[55][55];
void add(int a, int b, int c, int d)
bool spfa()}}
}return incf[t] > 0;
}int ek()
}return cost;
}int id(int i, int j, int sign)
int main()
}add(s, id(1, 1, 0), k, 0);
add(id(n, n, 1), t, k, 0);
for(int i = 1; i <= n; i ++)
}for(int i = 0; i < idx; i += 2)
printf("%d\n", -ek());
return 0;
}
方格取數 網路流
大致題意 給你乙個 n m 的矩陣,可以取任意多個數,但若你取了乙個數,那麼這個數上下左右的數你就都不能取,問能取到的最大值是多少。首先,我們可以把矩陣上的點都染成兩種顏色 第乙個點為黑色,它會影響的點為白色,這樣做下去 那麼我們就可以得到乙個二分圖,此時我們注意到,我們要做的是把這個二分圖按照衝突...
codevs1227(方格取數費用流)
給出乙個n n的矩陣,每一格有乙個非負整數aij,aij 1000 現在從 1,1 出發,可以往右或者往下走,最後到達 n,n 每達到一格,把該格仔的數取出來,該格仔的數就變成0,這樣一共走k次,現在要求k次所達到的方格的數的和最大 控制流量,每乙個格仔最多走一次,使費用最大,可以發現這是費用流。首...
codevs1227 方格取數2,費用流
傳送門 寫在前面 努力提公升寫網路流的能力 思路 建圖和蚯蚓很相似,不過這裡 i,j 拆出的兩個點x,y之間的邊有花費,實際點 i,j 與 i 1,j i,j 與 i,j 1 之間的連邊要流量inf費用為0,而且拆出的兩個點都要向 i 1,j i,j 1 的x點連邊,因為可能我們之前已經去過 i,j...