題解 足球聯盟

2022-05-05 19:42:11 字數 3030 閱讀 5000

就在土勻勻還在準備聯賽的時候,學霸

已經拿到了金牌。於是,開心的學霸

用他的筆記本玩起了足球聯盟。

足球聯盟裡有 \(n\) 只球隊,編號為 \(1\)~\(n\),

的球隊編號為 \(n\)。現在聯賽已經進行了很多輪,每個球隊都有了一定的積分。

聰明的通過對遊戲源**的分析,得到了接下來的所有賽程。

想,如果他可以控制所有剩下比賽的結果的話,能否使得他的球隊獲得比其他所有球隊都更高的分數。

積分的規則是:對於一場比賽,贏的球隊得 \(2\) 分,輸的球隊得 \(0\) 分,如果是平局,兩支球隊各得 \(1\) 分。

第一行為乙個整數 \(t\),表示資料組數。對於每組資料:

第一行為兩個正整數 \(n\) 和 \(m\),表示球隊的數目和剩餘比賽的數目。

第二行為 \(n\) 個非負整數,表示每個球隊現在的積分,不超過 \(1000\)。

接下來 \(m\) 行,每行兩個整數 \(x\)、\(y\),表示球隊 \(x\) 和球隊 \(y\) 之間有一場比賽。

每組資料一行,如果

能使自己的球隊獲得最高的分數(沒有並列),輸出yes,否則輸出no

測試時間限制 \(1000\ \mathrm\),空間限制 \(256\ \mathrm\)。

這道題是一道很有意思的題。要根據題中的限制來選擇演算法。

我們就假設那個人是 a 君。

列舉每一種比賽的勝負情況,再暴力算出來。

複雜度:\(\theta(3^mn)\)。

我們有必要想一下,有什麼結論可以使用。

如果有比賽是 a 君的球隊參加的,這場比賽 a 君的球隊必須贏

這是顯然的,這樣可以盡可能讓 a 君的球隊得分。

其他球隊不能贏太多分

這也是顯然的,因為贏的分數太多了就可能導致 a 君的球隊落選。

但是,對於剩下的球隊,我們難以指控。我們應該抽象一下這道題。

首先,有若干個數,每個數都有乙個初始值。

接下來,我們有若干個操作,可以將其中兩個數分別加上 \(a,b\),要求 \(a,b\in \mathbb\) 且 \(a+b=2\)

最後,我們要知道,是否存在一種操作,使完成所有操作後每個數都小於乙個給定的數。

當然,如果我們換一種表述,你就有可能發現這道題的正解:

有若干個水罐,每乙個水罐都有乙個固定容積,初始時為空。我們有若干個倒水措施,使得其中兩個水罐裡加起來能夠倒入 \(2\) 單位的水。

最後,我們想要知道,是否存在乙個倒水操作,使得所有的水罐都不會溢位。

沒錯,我們可以利用網路流來解決這個問題。

圖可以這樣設計:

畫出來就是這個樣子:

對應到這題上來,每乙個球隊的「容量」實際上就是能贏多少分,卻不會超過 a 君的球隊。

就是 a 君球隊的分數減去對應球隊分數再減一。

如果最後跑出來的最大流已經是 s 的滿流,那麼就是可以出線的。反之同理。

這樣,圖的複雜度是 \(\theta(n+m)\),再跑一遍網路流,複雜度就是 \(\mathcal((n+m)^3)\),基本跑不滿,可以通過本題。

(這裡的複雜度是以基本 isap 計算,如果用 hlpp 或者 lct 優化 isap 還能更快。)

又是又臭又長的**,但是核心還是很短的。

#include #include #include #include using namespace std;

const int max_n = 100, max_m = 1000, max_node = max_n + max_m + 1, max_edge = max_m * 3 + max_n, inf = 0x3f3f3f3f;

int hd[max_node], des[max_edge<<1], val[max_edge<<1], occ[max_edge<<1], nxt[max_edge<<1], edge_cnt = 0;

int hei[max_node], gap[max_node], cur[max_node], sco[max_n];

bool flag;

queueq;

inline int nid(int id)

inline int my_min(int a, int b)

inline int read()

if (ch == '-')

while (isdigit(ch))

return n * t;

}void _a(int s, int t, int v)

void add_edge(int s, int t, int v)

int aug(int s, int t, int lim)

gap[hei[s]]--, cur[s] = hd[s];

if (!gap[hei[s]])

flag = false;

hei[s]++, gap[hei[s]]++;

return flow;

}int main()

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

add_edge(nid(i), max_node - 1, sco[n-1] - sco[i] - 1);

} if (over)

continue;

for (int i = 0; i < max_node; i++)

cur[i] = hd[i];

hei[max_node-1] = 0, gap[0] = 1;

q.push(max_node - 1);

while (!q.empty())

}ta = 0;

while (flag)

ta += aug(0, max_node - 1, inf);

if (ta == rcnt * 2)

puts("yes");

else

puts("no"); }

return 0;

}

當時考場上做這道題時,第一感覺居然是 dp。後來才發現是網路流。

看來,這類圖論建模的題還要多多練習啊……

FC 熱血足球聯盟 記憶體使用記錄

pid player id 玩家編號,00 03。rid role id 角色編號,00 0b,有時0c對應球。tid team id 隊伍編號,00 01。一般方向 上為00,順時針每45度加20。0004,pid key a b select start u d l r 0008,pid cha...

足球比賽(d)題解

題目 2022 世界盃馬上就要開始了,經過一番激烈角逐,全球 32 支球隊獲得了出線資格。世 界盃的比賽分為兩個階段,分別為小組賽階段和淘汰賽階段,在小組賽階段 32 支球隊將分 成 8 個小組,每個小組 4 支球隊進行迴圈比賽,即每兩支球隊比賽一次,每支球隊會進行 3 場比賽,勝得 3 分,平得 ...

足球聯賽的題解

在足球聯賽中,小組中的隊伍之間會舉行若干場比賽。一場比賽中,勝者得 3 分,敗者 不得分,平局則雙方各得一分。現在已知隊伍的個數 t 已經結束的比賽場數 n,以及當前每支隊伍的總分 ai,請求出 這 n 場比賽中有多少場是平局。我們發現一場比賽 所以,平局場數 比賽常數 times 3 所有球隊的計...