題目大意:有乙個$n\times m$的切糕,每乙個位置的高度可以在$[1,k]$之間,每個高度有乙個代價,要求四聯通的兩個格仔之間高度最多相差$d$,問可行的最小代價。$n,m,k,d\leqslant 40$
題解:網路流,不考慮相差為$d$的條件時,可以給每個位置建乙個點,源點連向高度為$1$的點容量為$\infty$,高度為$i$的點連向這個位置高度為$i+1$的點,容量為代價,高度為$k$的連向匯點,容量為代價。跑最小割。
考慮相差為$d$的條件,可以對於相鄰的兩個點$a,b$,連線$a_i\to b_$的容量為$\infty$的邊這樣就強制限定兩個點的最小割必須相距小於等於$d$,跑最小割即可
卡點:加邊的時候多加了$k$倍,導致又$tle$又$re$
c++ code:
#include #include #include const int inf = 0x3f3f3f3f;namespace std
inline istream& operator >> (int &x)
#undef m
} cin;
struct ostream
static int s[20], *top; top = s;
while (x)
for (; top != s; --top) *++ch = *top;
return *this;
} inline ostream& operator << (const char x)
inline ~ostream()
#undef m
} cout;
}namespace network_flow e[maxm << 1];
void addedge(int a, int b, int c) ; head[a] = cnt;
e[++cnt] = (edge) ; head[b] = cnt;
} int st, ed, n, mf;
int gap[maxn], dis[maxn], q[maxn], h, t;
void init()
}} }
int dfs(int u, int low)
} if (!--gap[dis[u]]) dis[st] = n + 1;
++gap[++dis[u]], lst[u] = head[u];
return res;
} void isap(int s, int t)
}int n, m, h, d;
int v[50][50][50];
int pos[50][50][50], idx, st, ed;
void addedge(int x, int y, int z, int w)
int main()
st = 0, ed = ++idx;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
if (i != 1) addedge(i, j, i - 1, j);
if (i != n) addedge(i, j, i + 1, j);
if (j != 1) addedge(i, j, i, j - 1);
if (j != n) addedge(i, j, i, j + 1);
} network_flow::isap(st, ed);
std::cout << network_flow::mf << '\n';
return 0;
}
洛谷3227 切糕(最小割)
題目描述 經過千辛萬苦小 a 得到了一塊切糕,切糕的形狀是長方體,小 a 打算攔腰將切糕切成兩半分給小 b。出於美觀考慮,小 a 希望切面能盡量光滑且和諧。於是她找到你,希望你能幫她找出最好的切割方案。出於簡便考慮,我們將切糕視作乙個長 p 寬 q 高 r 的長方體點陣。我們將位於第 z層中第 x ...
洛谷 P3197 HNOI2008 越獄
來來來,日常水一篇 滑稽 監獄有連續編號為1 n的n個房間,每個房間關押乙個犯人,有m種宗教,每個犯人可能信仰其中一種。如果相鄰房間的犯人的宗教相同,就可能發生越獄,求有多少種狀態可能發生越獄 輸入格式 輸入兩個整數m,n.1 m 10 8,1 n 10 12 輸出格式 可能越獄的狀態數,模1000...
洛谷 P1437 HNOI2004 敲磚塊
在乙個凹槽中放置了 n 層磚塊 最上面的一層有n 塊磚,從上到下每層依次減少一塊磚。每塊磚 都有乙個分值,敲掉這塊磚就能得到相應的分值,如下圖所示。14 15 4 3 23 33 33 76 2 2 13 11 22 23 31如果你想敲掉第 i 層的第j 塊磚的話,若i 1,你可以直接敲掉它 若i...