1. 程式人生 > >2017 UESTC Training for Graph Theory 題解

2017 UESTC Training for Graph Theory 題解

傳送門

A題 生成樹

對邊排序,列舉最小邊,然後不斷加邊,直到1,n在一個生成樹中,用最大邊更新答案
程式碼

B題 Dijkstra+構造

題意:給出一個大小為n的集合S,集合裡有n個互不相同正整數.
有q個詢問,每次詢問是否能選擇S中的一些數字 ( 同一個數字可以選擇多次,也可以任何數字都不選),使它們相加的和為m.

本題思考的啟發點是n和a1的資料比較小
對於S集合中的數,例如a1,考慮到如果x能夠被表示出來,那麼x+a1也一定能被表示出來。
故設d[r]為所有模a1餘r的數中,能被表示出來的最小的數。
故可以表示出一個a1個節點a1*n條邊的有向圖。
d[0] = 0,丟入優先佇列,然後對於q.top()的點連出的n條邊進行鬆弛操作。
如果 d[u] + a[i] < d[(d[u] + a[i])] 則重新整理並丟入佇列。
跑出來的d[i],如果d[i] != INF則都是可以表示出來的。
對於每個詢問判斷 q >= d[q % a[1]]即可。
複雜度n

a1loga1
程式碼

D題 拓撲排序

比較兩個相鄰字串,對不同的字元建有向邊,然後用拓撲排序,每次取出度數為0的字典序最小的小寫字元去做,需要注意的是當兩個字串字串前半部分相同,第二字串比第一個短則不能構造出答案
程式碼

G題 Tarjan縮點+dfs

如果不逆行,那麼答案就是1所在的強連通分量的點數
如果逆行了,那麼逆行的邊必然在縮點後的拓撲圖上
假設逆行的邊為u->v,那麼該回路可分為1到v和u到1兩部分
經過的最多點數即1到v與u到1路徑上的最大點權和減去1的點權
(這裡的點指的都是縮點後的點)
那麼預處理拓撲圖上1到每個點的最大點權和及每個點到1的最大點權和
列舉逆行的邊即可得到答案。
剛開始dfs內部順序寫的有點問題,wa了半天

程式碼

H題 最小生成樹

題意:
有一個長度為n的未知的01序列
詢問區間l,r的異或和代價為C[l][r]
求通過詢問得到該序列的最小代價

可以證明出詢問集合構成的圖有n條邊且沒有迴路
建立n+1個虛擬點0到n,對於詢問區間[l,r],在l-1與r之間連邊,邊權為C[l][r]
那麼能得到該序列的極小詢問集合會構成這n+1個點的一個生成樹,代價為邊權和
程式碼

I題 鼓輪模型+歐拉回路

參考here,可以百度鼓輪模型的構造方法

程式碼

J題 差分約束

令sum[i]表示前i項的和(0<=i<=n,sum[0]=0)
那麼題目的條件可轉化為:
sum[i]-sum[i-p]>=s (p<=i<=n)
sum[i]-sum[i-q]<=t (q<=i<=n)
將第一個不等式取反,得到
sum[i-p]-sum[i]<=-s(p<=i<=n)

考慮最短路徑的性質,令dis[i]表示從s到i的最短路,則對於圖中存在的一條邊(u,v),有
dis[v]<=dis[u]+w(u,v),即dis[v]-dis[u]<=w(u,v);
類比不等式,於是可建圖,i向i-p引長度為-s的邊,i-q向i引長度為t的邊。

跑spfa,如果存在負環,則無解,
否則所得到的最短路的值就是sum[i]的一個解。

程式碼