CQOI2017 老C的方塊

2021-08-04 22:06:01 字數 1776 閱讀 2422

傳送門:nkoj4042

這是一道網路流題。我在這道題上耗了很久=-=,感謝@oblack幫我修改**。

這道題的思維上的難度並不大。

以下是我的想法:

首先要確定乙個大的方向,題目中要求移除一些方塊使得剩餘方塊無法構成「討厭的形狀」,很容易就想到了最小割。

仔細觀察一下,可以發現這些討厭的形狀是由兩個方格+一條特殊的邊+兩個方格按不同方向擺放而成的。

於是可以根據觀察所得將網格染成如圖4種顏色:

討厭的形狀便是根據「淺橙—紅—淺棕—深棕」或「深棕—紅—淺棕—淺橙」的順序構成的。

談談建圖:

如上圖,藍色邊容量為方格的權值,粉色邊容量為inf,黃色邊容量為相關聯的兩個方格中較小的權值。

建好圖就可以愉快地跑sap了。(提醒自己以後pid要賦初值,因為1^1=0而我想要找的是2號邊。要更細緻些啊,向oblack學習(ง •_•)ง)

放出渣**嚇人:

#include

#include

#include

#define ll long long

const

int maxn=400005;

const ll inf=1e10;

using

namespace

std;

ll to[maxn<<1],next[maxn<<1],last[maxn],pid=1;

ll c,r,n,s,t;

ll w[maxn];

struct node pane[maxn];

mapid;

void storepath(ll u,ll v,ll w)

ll getid(ll x,ll y)

ll judge(ll x,ll y)

t=(x+2)%4;

if(t)return t+4;

return8;}

void u_d_in(ll i,ll x,ll y)

void u_d_out(ll i,ll x,ll y)

void fl_in(ll i,ll x,ll y)

}void tl_out(ll i,ll x,ll y)

}void tr_out(ll i,ll x,ll y)

}void fr_in(ll i,ll x,ll y)

}void build()

} else

if(co==2||co==6)

} else

if(co==3||co==8) else

}}ll dis[maxn],cnt[maxn];

ll sap(ll u,ll flow)

if(!--cnt[dis[u]])dis[s]=t;

cnt[++dis[u]]++;

return out;

}int main()

s=n+1,t=s+1;

build();

ll ans=0;

while(dis[s]printf("%lld",ans);

return

0;}

CQOI2017 老C的鍵盤

發現題目給的很像一棵樹。就把這棵樹建出來。發現如果把大於小於號分別看成一條有向邊,發現這個題目就是求這個圖有多少個拓撲序。對於每乙個拓撲序,直接 12345 這樣標號就可以得到滿足題目要求的序列。考慮樹 dp 設 f i,j 為 i 這個點在這個子樹所形成的拓撲序列中在第 j 位的方案數。轉移的時候...

CQOI2017 老C的鍵盤

一句話題意 給你一棵完全二叉樹,每條邊有乙個方向,求這棵樹有多少種不同的拓撲序。簡化題意後,其實就是乙個普及組樹形 dp。設 dp i,j 表示以點 i 為根的子樹中,i 號點排第 j 名的方案數。利用 j 這個輔助維,我們可以列舉點 i 的排名 k 掃一遍點 i 的所有兒子,每次會新來乙個以 v ...

題解 CQOI2017老C的鍵盤

建議大家還是不要閱讀此文了,因為我覺得這題我的解法實在是又不高效又不優美 只是想要記錄一下,畢竟是除了中國象棋之外自己做出的組合dp第一題 首先如果做題做得多,比較熟練的話,應該能一眼看出這題所給的資訊正好描述的是一棵二叉樹上父子的大小關係。於是確立乙個狀態 f u i 表示在 u 及 u 的子樹內...