就在土勻勻還在準備聯賽的時候,學霸
已經拿到了金牌。於是,開心的學霸
用他的筆記本玩起了足球聯盟。
足球聯盟裡有 \(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 所有球隊的計...