題目描述:
眾所周知,tt 有乙隻魔法貓。
這一天,tt 正在專心致志地玩《貓和老鼠》遊戲,然而比賽還沒開始,聰明的魔法貓便告訴了 tt 比賽的最終結果。tt 非常詫異,不僅詫異於他的小貓咪居然會說話,更詫異於這可愛的小不點為何有如此魔力?
魔法貓告訴 tt,它其實擁有一張遊戲勝負表,上面有 n 個人以及 m 個勝負關係,每個勝負關係為 a b,表示 a 能勝過 b,且勝負關係具有傳遞性。即 a 勝過 b,b 勝過 c,則 a 也能勝過 c。
tt 不相信他的小貓咪什麼比賽都能**,因此他想知道有多少對選手的勝負無法預先得知,你能幫幫他嗎?
輸入:第一行給出資料組數。
每組資料第一行給出 n 和 m(n , m <= 500)。
接下來 m 行,每行給出 a b,表示 a 可以勝過 b。
輸出:對於每一組資料,判斷有多少場比賽的勝負不能預先得知。注意 (a, b) 與 (b, a) 等價,即每乙個二元組只被計算一次。
sample:
input:
33 3
1 21 3
2 33 2
1 22 3
4 21 2
3 4output:00
4題目思路:
本題是乙個求路徑的問題,按照資料可以判斷複雜度為o(n^3),所以可以用floyd演算法。我們把所有可能的勝負關係組成乙個二維陣列,如果值為1那就是有勝負關係,為0就是沒有勝負關係,如果對稱的都為0也就是二者之間不知道勝負關係,那麼這就是我們要找的答案。所以問題就轉換為如何實現傳遞的勝負關係呢?當然可以按照ppt裡面的方案就可以,不過要注意直接寫會導致tle,所以我們要修改
首先是陣列的距離問題,上面表示的是兩點距離,數的範圍是非負整數,但是我們本體並不需要求兩個點的具體的距離,只需要判斷是否連通即可。所以我們可以看到,上面那個min對於bool範圍的資料來說,就可以用按位或符號來表示,因為要想連通那就得是1,那麼兩個數誰是1就取代誰,這個min的思路是一樣的。對於加號,我們可以取按位與運算,因為要想使後者取代前者,那麼就需要後面兩個點都是聯通的(也就是i->k,k->j得到i->j),兩個點都得是1就可以用按位與表示。
a[i]
[j]=a[i]
[j]|
(a[i]
[k]&a[k]
[j])
;
當然如果只改了這一句就去提交是tle的,所以我們發現乙個問題——剪枝!也就是要把一些根本不可能出現的情況給他排除掉,對於圖來說,陣列對角線是不可能有數值的,所以for列舉之後遇到對角線就可以直接跳過了。
if
(k==i)
continue;if
(k==j||j==i)
continue
;
同樣的道理,我們上面的距離運算是按位或運算,如果按位或左邊已經是1了,那麼後面根本不需要在算了,所以這樣也得跳過
if
(!a[i]
[k])
continue
;
求完了所有可能的通路之後,我們就可以去求誰還沒有通路了,為了省時間,我們可以只列舉上半部分,但是判斷的時候還是要判斷對稱的兩個部分是否都是0,都是0才符合要求。
for
(int i=
1;i<=n;i++
)}
**如下:
#include
#include
using
namespace std;
bool a[
600]
[600];
intmain()
for(
int k=
1;k<=n;k++)}
}for
(int i=
1;i<=n;i++)}
cout<
}}
第七周作業作業
1 自建yum倉庫,分別為網路源和本地源 建立yum配置檔案,類似如下 base name base baseurl file misc cd gpgcheck 0 epel name epel baseurl gpgcheck 0 enabled 1 本地源 以前自己整理的 2 編譯安裝http2...
第七周作業
書中習題1 說說下列程式的執行過程和運算結果 include includeusing namespace std double squ double x 函式原形 int main 主函式 書2,不用庫函式,求整數次冪 3.程式設計實現輸入兩個4x5矩陣和5x3矩陣,定義函式並在主函式中呼叫計算它...
第七周作業
1 列舉常見的核心引數以及引數的意義 1 net.ipv4.ip forward 資料報的路由 開關,設定為1表示開啟,0表示關閉。2 vm.drop caches 清空caches,釋放記憶體占用。設定為1表示清空 pagecache,設定為2表示清空 dentries 和 inodes,設定為3...