JSOI2014 學生選課

2022-05-02 02:12:09 字數 1688 閱讀 5191

傳送門

看到這題首先可以二分。

考慮對於當前的 \(mid\) 如何 \(\text\)

我們用 \(f_\) 來表示 \(i\) 對 \(j\) 的好感度排名,那麼對於兩個人 \(i\),\(j\) 如果有 \(\max\, f_\} > mid\) 那麼顯然這兩個人是不能上同乙個老師的課的。

而且每個人可以上的課只有兩種,我們記為 \(a_\)

假設 \(i\),\(j\) 對於當前的 \(mid\) 而言不能分在一起,其中 \(a_ = a_\),那麼我們可以發現:

可以發現這就是乙個裸的 \(\text\)

所以我們每次 \(\text\) 都建圖跑一遍 \(\text\) 就好了。

參考**:

#include #include #define rg register

#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)

template < class t > inline t min(t a, t b)

template < class t > inline t max(t a, t b)

template < class t > inline void read(t& s)

const int _ = 1010;

int tot, head[_ * 3]; struct edge edge[_ * _ * 4];

inline void add_edge(int u, int v) , head[u] = tot; }

int n, t[_], a[_][2], f[_][_];

int num, dfn[_ * 3], low[_ * 3], col, co[_ * 3], top, stk[_ * 3];

inline void tarjan(int u)

if (low[u] == dfn[u]) }

inline int id(int x, int y)

inline void init()

inline bool check(int mid)

if (a[i][0] == a[j][1])

if (a[i][1] == a[j][0])

if (a[i][1] == a[j][1])

}for (rg int i = 1; i <= n; ++i)

for (rg int k = 0; k < 3; ++k)

if (t[i] != k && !dfn[id(i, k)]) tarjan(id(i, k));

for (rg int i = 1; i <= n; ++i)

if (co[id(i, a[i][0])] == co[id(i, a[i][1])]) return 0;

return 1;}

int main()

for (rg int i = 1; i <= n; ++i)

for (rg int j = i + 1; j <= n; ++j) f[i][j] = max(f[i][j], f[j][i]);

int l = 1, r = n - 1;

while (l < r)

printf("%d\n", l);

return 0;

}

JSOI2014 歌劇表演

傳送門 沒想到吧我半夜切的 這道題應該算是 text 裡面比較簡單的吧。考慮用集合關係來表示分辨關係,具體地說就是我們把所有演員分成若干個集合,滿足同乙個集合內的演員兩兩不能分辨。初始時所有演員位於同乙個集合內。然後對於某次參加了演出的演員,他們可能分別來自不同的集合,那麼這些集合就會有兩類不同的組...

JSOI2014 歌劇表演

我們抽象的認為一些不能互相辨認的人,被分到了乙個集合,每當又有一場演出,就將每個出演的演員扔出集合,再將上次在相同集合的分在同一集合。然後修改被分的集合和被新建立的時間,當集合只有乙個數的時候不可再分。輸出每個演員所在的集合的最後修改時間,僅當該演員所在的集合中只有乙個演員。include incl...

JSOI2014 解題報告 小結

考的主要是dp 貪心 資料結構這一些,還有網路流的題因為還沒學就先暫時沒寫,有時間還是要把沒學的東西給補上來,同時也要多做一點省選的題目提高思維能力 三分 貪心,可以感性理解一下這個能宅的天數與叫外賣的次數為什麼是乙個單峰函式,如果叫外賣叫的少,那麼費用就高,叫外賣叫的多,那麼給外賣小哥的錢就很多,...