費用流 2017 山東一輪集訓 Day4 棋盤

2021-10-03 20:39:39 字數 2028 閱讀 9875

求放k個棋子在n*n的棋盤上,最少互相攻擊的棋子對數。

能夠攻擊僅當兩旗子在一條直線上,且中間無障礙物。

共有q個詢問

不難想到這種棋盤上放棋子的題考得是網路流

積累:按行、縱分別按其對應連通塊編號,s->行->縱->t

但明顯新一行的點互相攻擊的話,隨點數的增加,貢獻是0,1,2,3這樣遞增的。

於是我們想到給s->行,縱->t連邊時 連多條(val=0,1,2,3…,flow=1)的邊

最後 行->縱 連(val=0,flow=1)即可

好像忘了一件事,多個詢問,用費用流每次增一條路,預處理出來就行

注意預估邊條數和點個數

#include

using

namespace std;

const

int n=

6e3+

10,m=

2e5+

10,q=

1e3+

10,inf=

1e9+7;

int s,t,max_flow;

int n;

int head[n]

,nex[m]

,to[m]

,flow[m]

,val[m]

,tot=1;

void

build

(int u,

int v,

int f,

int w)

int mp[55]

[55];

int bl[2]

[55][

55];void

make_build()

else bl[0]

[i][j]

=re0,pre0=0;

}re0++

;pre0=1;

}int re1=

1,pre1=0;

for(

int i=

1;i<=n;i++

)else bl[1]

[i][j]

=re1,pre1=0;

}re1++

;pre1=1;

}//pre用來盡量壓點個數,但可能沒什麼用

s=0,t=re0+re1+

1,max_flow=t;

for(

int i=

1;i<=re0;i++

)for

(int k=

0;k)build

(s,i,

1,k)

;for

(int i=

1;i<=re1;i++

)for

(int k=

0;k)build

(i+re0,t,

1,k)

;for

(int i=

1;i<=n;i++

)for

(int j=

1;j<=n;j++)}

int dis[n]

,flw[n]

,pre[n]

;bool vis[n]

;bool

spfa()

}}return dis[t]

<

0x3f3f3f3f;}

intdoit()

}return tmp;

}int q;

int ans[

2510];

struct qus

}qu[q]

;char s[55]

;int

main()

make_build()

;for

(int i=

1;i<=all;i++

) ans[i]

=ans[i-1]

+doit()

;scanf

("%d"

,&q)

;for

(int fw,i=

1;i<=q;i++

)return0;

}

2017 山東一輪集訓 Day4 基因

設定 sqrt 個關鍵點,維護出關鍵點到每個右端點之間的答案以及pam的左指標,每次暴力向左插入元素即可,為了去重,還需要記錄一下pam上每個節點在每個關鍵點為左端點插入到時候到最左邊出現位置,總複雜度 o n sqrt program by mangoyang pragma gcc optimiz...

2018山東一輪集訓 Tree

為什麼出題人這麼毒瘤啊?乙個分塊還要帶log的題非要出成n 2 1e5。為了卡過最後兩個點我做了無數常數優化,包括但不限於 把所有線段樹改成 存差分的樹狀陣列 把樹剖求lca的極小的log優化成rmq o 1 求lca 根據測試情況手動調整siz的大小 但就是死也卡不過去,算了算了qwq 常規套路,...

2017 山東一輪集訓 Day7 逆序對

題解 滿滿的套路題。首先顯然從大到小列舉 然後每次生成的逆序對是1 i 1 的 這樣做dp是nk的 複雜度太高了 那我們轉化一下問題 變成sigma ai ai 據說是個經典問題。感覺非常奇妙 先容斥一下,也就是說 總的 至少1個條件不滿足 至少2個條件不滿足 那考慮一下如何算有x個條件不滿足 不滿...