图论姿势太弱,这套题做了好久。。
A:枚举最短那条边,然后最小生成树那种操作,1 和 n 联通就算答案
B:考虑到假如我们能凑出x的话,那很明显我们也能凑出任意数表示x + ai,考虑选取一个ai,然后dis[x]表示能凑出k % ai == x的最小k,跑一次最短路,初始化dis[0] = 0,假设选择的ai为A,然后0 - A-1对于每个数ai都连一条边则dis[(u + aj) % A] = min(dis[(u + aj) % A],dis[u] + aj);判断的时候if(X >= dis[X%A])
C:我的zz做法是这样的,行列拆开,源点往每一行连一条(Rowcnt[i]/2,(Rowcnt[i] + 1)/2)上下界的边,每一列对汇点也这样连,对于每个点,行列连一条(0,1)上下界的边,然后跑一次上下界可行流。。。不过TLE了好几发,优化一下过了,估计不是正经做法。
D:拓扑排序。先建图,对于第i个名字和i+1个名字,找出第一个不同的字母,然后就可以连一条边,不过如果第i+1个名字是第i个名字的前缀的话,那很明显是无解的
E:差分约束,跑一次最大,一次最小就好了
F:考虑从安全点倒着跑,因为安全点是确定的,能到达安全点的肯定对可达安全点/安全点的点连了d+1条边,所以倒着来做一次dij,对于前d次的更新直接忽略,因为这d次都是会被封锁的,所以更新到d+1次的时候这个点就已经确定了,把这个点相连的边加进堆里,继续更新,直到没有确定的点。
G:先缩点,那就有一个dag图了,对于逆行一条边(u,v),显然逆行之后必须要(1 - > v,u > 1)才会加答案,把这条边去掉不看的话,就是出现了两条链,所以对于dag图,正向反向跑一次dp,dp[i]表示1到i最长经过几个点,rdp[i]表示i到1最长经过几个点,然后枚举每条边答案就更新为max(dp[v] + rdp[u] - size[1])
H:A1...An,n个变量,每个Ci,j都是一个有关变量的方程,n个变量n个方程,跑一次最小生成树。
I:暴力dfs即可
J:考虑把条件转化成Sum[i] - Sum[i - p] >= s ,Sum[i] - Sum[i - q] <= t,然后跑一次差分约束
K:离散下直接最短路