BZOJ5251 八省聯考2018劈配(網路流)

2022-05-22 00:48:09 字數 1808 閱讀 2097

劈配,匹配,網路流。那麼考慮怎麼跑網路流。

先看第一問。首先套路的建出超源超匯。不用想也知道導師向匯連容量為戰隊人數上限的邊。特別地,給出局也建乙個點,向匯連容量inf的邊(似乎沒有必要)。對於乙個新學員,假設我們已經知道了之前的學員的最優選擇,可以把之前的每名學員和可以選擇的導師連邊,並由源向學員連容量為1的邊。然後對於該名新學員,先只連最優選擇的邊,如果此時跑出的最大流不等於學員數,則表明這名學員無法選擇最優,那麼刪掉最優邊(此時這些邊裡一定沒有流量,可以通過容量改為0實現)並連上次優邊,次優邊還是不行的話繼續,一直這樣下去直到最大流等於學員數。第一問就做完了。至於複雜度,o(能過)。

然後是第二問。對於每個人可以二分答案,然後跑最大流看其是否滿足。似乎需要訪問網路的歷史狀態?可持久化網路流!這玩意似乎沒法可持久化啊……那就暴力記下來唄。由於有c的限制,這裡面的邊不會很多。於是就做完了,o(能過)。還有一種做法是先連上該學員可以選擇的邊,然後從第一名開始依次把最優選擇加進去跑,直到無法滿足,可能會快不少。

#include#include

#include

#include

#include

#include

#include

using

namespace

std;

intread()

while (c>='

0'&&c<='

9') x=(x<<1)+(x<<3)+(c^48),c=getchar();

return x*f;

}#define n 210

#define s 0

#define t 404

int test,c,n,m,b[n],s[n],p[n<<1

],cnt[n],t;

int cur[n<<1],d[n<<1],q[n<<1

],ans,cho[n];

vector

a[n][n];

struct dataedge[n*n<<2],hisedge[n][2510

];void addedge(int x,int y,int

z)void addedge(int x,int y,int cap,int

flow)

void

init()

a[i][m+1].push_back(m+1

); }

for (int i=1;i<=n;i++) s[i]=read();

}bool

bfs()

}while (headreturn ~d[t];

}int work(int k,int

f)

if (used==0) d[k]=-1

;

return

used;

}void

dinic()

}int

main()

for (int k=tmp+1;k<=t;k+=2) edge[k].cap=0

; }

for (int j=0;j<=t;j+=2

)

if (edge[j].cap) hisedge[i][++cnt[i]]=edge[j],hisedge[i][cnt[i]].nxt=edge[j^1

].to;

}/*for (int i=0;i<=n;i++)

printf(

"%d

",i-add-1

); }

cout

<}

return0;

}

Bzoj5251 線段樹 貪心

bzoj5251 線段樹 貪心 記錄本蒟蒻省選後的第一篇題解 國際慣例的題面 首先這個東西顯然是一棵樹。如果我們把數值排序,並建立這棵樹的dfs序,顯然dfs序上的乙個區間對應數值的乙個區間,且根為數值區間左端點。如果你這樣想,恭喜你能獲得50分,如果記得加了eps會獲得55 60分。因為當數值可以...

八省聯考2018 劈配

題目這題目,乍一眼看上去像乙個dp,因為這個資料範圍一般都是dp,但是考慮到轉移有後效性,所以顯然是做不了dp的。考試的時候像著怎麼設狀態沒有後效性,失敗了,就只打了乙個70分的暴力,還掛了20分。這題其實是個 網路流 匹配 真心看不出,然後我寫部落格的時候旁邊yl神犇看見了,嘲諷了我一波,我是真的...

八省聯考2018 劈配

題解 這題思路就是暴力。主要在於分析複雜度?dinic跑二分圖 msqrt n 這題好像用不到。首先這是個匹配問題顯然需要利用網路流 考慮第一問 每一次我們就暴力按照志願順序加入邊 直到二分圖匹配數 1 這個複雜度是 nm nm 的 因為一次只增廣一條邊所以每次是nm的,不過這個很明顯是跑不滿而且差...