給定乙個\(n \times m\)方格矩陣,每個格仔可在\(0,1,2\)中取值。要求在方格的邊上進行劃分,使得任意聯通塊內不同時包含\(1\)和\(2\)的格仔。
若對方格矩陣的形式感到困惑,我們可以先考慮圖上的形式。
假設圖中有節點\(w_1\),\(q_1\),\(s_1\),\(s_2\),且\(w_1\)與其它三者間各有一邊,此外\(q_1\)和\(s_1\)間還有一邊。\(w_1\)是1值節點,\(s_1,s_2\)是2值節點。現在考慮進行劃分。
我們發現在原問題中,\(0\)值點無論和哪個點劃在乙個連通塊內都是合法的。換言之,\(0\)值節點在這裡只起到傳導連通的作用。亦即任意兩個連通節點間可以有任意個\(0\)值節點。
根據這一性質,我們對圖進行分層。建立網路,將\(w_i\)作為第一層(靠近源點),\(s_i\)作為最後一層(靠近匯點),\(q_i\)放中間。將原圖中的連線關係單向地對應到網路中:
容易發現,由於原圖是無向圖,我們在建立流網路時對其定向,從而避免對乙個劃分邊的重複計算。而定向的依據則是依據\(w_i > q_i > s_i\)的優先順序順序進行的。
這樣建圖後,求出的最大流就是流網路的最小割,也就是答案。
分析完圖上的情況後,這裡的情形就顯得簡單了。
我們考慮對任意格仔\((i,j)\),其四周的格仔即是上文中與之直接相連的節點。我們將圖中的關係放到方格矩陣中處理就可以了。
#include#include#include#include#include#include#define g g
using namespace std;
struct item;
item item(int _p,int _v,int _c)
vector g[100005];
int n,m,t1,t2,t3,dis[100005],d[100005],vis[100005],s,t,t4,costs=0,tans,ans,inc[100005],cnt=0,k,inp[100005][4],edg[100005];
vector oppo[100005];
int dinic_spfa()}}
return dis[t]>0;}
int dinic_dfs()
return a;}
int dinic_main(int src,int dest)
void build(int w,int x,int y,int z)
int main()
ZJOI2009 狼和羊的故事
點此看題 考查網路流的建圖,要把羊和狼分割開來,很容易想到最小割問題,下面講一下建圖的方法 然後我們的圖就建出來了,這時候跑最大流就是答案。include include include include define inf 0x3f3f3f3f const int maxn 10005 using...
ZJOI2009 狼和羊的故事
solution 考慮 1 和 2 相鄰是必須要長度為 1 的籬笆,所以只需考慮 1,2 和 0 之間要不要放籬笆,用 s 連向所有的 1 所有的 2 連向 t 現在問題是要使 s 與 t 不連通,這不是經典的最小割問題嗎?code include include includeusing name...
題解 ZJOI2009 狼和羊的故事
題目戳我 text 顯然思路,把所有羊看成乙個源點,所有狼看成乙個匯點,格仔之間連容量為 1 的邊,直接跑最小割。技巧 這題收穫 注意到無限邊在最小割中特殊的意義。includeusing namespace std define int long long const int maxn 5e5 1...