題目鏈結
這題能想到費用流就不難做了
從s向(1, 1)連費用為0,流量為k的邊
從(n, n)向t連費用為0,流量為k的邊
對於每個點我們可以拆點限流,同時為了保證每個點只被經過一次,需要拆點。
對於拆出來的每個點,在其中連兩條邊,一條為費用為點權,流量為1,另一條費用為0,流量為inf
相鄰兩個點之間連費用為0,流量為inf的邊。
跑最大費用最大流即可
#include#define pair pair#define mp(x, y) make_pair(x, y)
#define fi first
#define se second
#define int long long
#define ll long long
#define fin(x)
#define fout(x)
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<22, stdin), p1 == p2) ? eof : *p1++)
//char buf[(1 << 22)], *p1 = buf, *p2 = buf;
using namespace std;
const int maxn = 51, max = 1e5 + 10, mod = 1e9 + 7, inf = 1e9 + 10;
const double eps = 1e-9, pi = acos(-1);
template inline bool chmin(a &a, b b) return 0;}
template inline bool chmax(a &a, b b) return 0;}
template inline ll add(a x, b y)
template inline void add2(a &x, b y)
template inline ll mul(a x, b y)
template inline void mul2(a &x, b y)
template inline void debug(a a)
template inline ll sqr(a x)
inline int read()
while(c >= '0' && c <= '9') x = (x * 10 + c - '0') % mod, c = getchar();
return x * f;
}int n, k, s = 0, t = 1e5 - 1, a[maxn][maxn], dis[max], vis[max], pre[max], id[maxn][maxn][2], cnt, maxcost;
struct edge e[max];
int head[max], num;
inline void add_edge(int x, int y, int w, int f) ;
head[x] = num++;
}inline void ae(int x, int y, int w, int f)
bool spfa() }}
return dis[t] > -inf;
}void f()
void mcmf()
signed main()
} mcmf();
printf("%d", maxcost);
return 0;}/*
3 21 2 3
0 2 1
1 4 2
*/
洛谷P2045 方格取數加強版
傳送門 一看題意,發現第二次取就是0了,那麼就想到了網路流 其實是看標籤 費用流建圖 1.首先s向 1,1 連一條費用為0,容量k的邊 2.然後 n,n 向t連一條費用為0,容量k的邊 3.每個點 i,j 向 i 1,j 和 i,j 1 連一條費用0,容量k的邊 此處注意判邊界 4.每個點拆成入點和...
洛谷P2045 方格取數加強版
題目 link 網路流 費用流 一道比較好建模的題,重點是怎樣讓每個數隻被取一次 控制每個點被走的次數,我們可以很容易想到拆點 對於每個點,我們在入點和出點之間連兩條邊,一條流量為 1 11,費用為該格仔的權值 另一條流量為 infty 費用為 0 00。除此之外,每個點還要分別向右邊和下面的連邊,...
P2045 方格取數加強版
給出乙個n n的矩陣,每一格有乙個非負整數aij,aij 1000 現在從 1,1 出發,可以往右或者往下走,最後到達 n,n 每達到一格,把該格仔的數取出來,該格仔的數就變成0,這樣一共走k次,現在要求k次所達到的方格的數的和最大 輸入格式 第一行兩個數n,k 1 n 50,0 k 10 接下來n...