Aiiage Camp Day5 A Rikka with Linker
生活随笔
收集整理的這篇文章主要介紹了
Aiiage Camp Day5 A Rikka with Linker
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意
n個點,m個關系。a依賴b則a需要出現在b前。
求滿足所有關系的最短序列長度。
n<18, m<n(n-1)
?
題解
問題事實上等價于有向有環圖的拓撲排序。
所以用拓撲排序結合搜索有個顯然的2^n*n^2的做法。
賽場上寫的有點丑T了。
標算是DP。F[S]表示添加了集合S的最短長度。對于每個S,枚舉添加點x:若x被依賴的所有點都出現過,則只需要在當前序列最后添加x;否則,需要在最后再添加一個x使尚未添加的點滿足條件。
復雜度O(2^n*n)。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int h[30], f[300000]; 5 6 int main() 7 { 8 int T; 9 for (scanf("%d", &T); T; T--) 10 { 11 memset(h, 0, sizeof(h)); 12 int n, m; 13 scanf("%d%d", &n, &m); 14 for (int i = 0; i < m; ++i) 15 { 16 int u, v; 17 scanf("%d%d", &u, &v); 18 h[v] ^= 1 << (u - 1); 19 } 20 int maxx(pow(2, n)); 21 for (int i = 0; i < maxx; ++i) 22 f[i] = 2 * n; 23 f[0] = 0; 24 for (int i = 0; i < maxx; ++i) 25 for (int j = 1; j <= n; ++j) 26 if (!(i & (1 << (j - 1)))) 27 if ((h[j] ^ i) & h[j]) 28 f[i ^ (1 << (j - 1))] = min(f[i ^ (1 << (j - 1))], f[i] + 2); 29 else 30 f[i ^ (1 << (j - 1))] = min(f[i ^ (1 << (j - 1))], f[i] + 1); 31 printf("%d\n", f[maxx - 1]); 32 } 33 34 return 0; 35 }?
轉載于:https://www.cnblogs.com/aseer/p/8479842.html
總結
以上是生活随笔為你收集整理的Aiiage Camp Day5 A Rikka with Linker的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ES6 使用数据类型Set求交集、并集
- 下一篇: 【独立游戏】黎明之刃——3D硬核ARPG