JZOJ5004. Fortress
来源:互联网 发布:virtualbox ubuntu 64 编辑:程序博客网 时间:2024/04/28 15:41
题目大意
有
初始时所有敌人的耐久都为5。敌人造成的伤害如下表:
求最坏情况下,敌人最多能造成多少伤害。
Data Constraint
题解
和WC2016挑战NPC的思想类似,考虑将问题转化为最大匹配问题。
将一个敌人拆成7个点,如图:
如果有一个炮可以打到这个敌人,就向外面五个点连边。现在可以发现,当外面有1个已经被匹配时,剩余的点有3个匹配;2个被匹配时,剩余2个匹配;3个被匹配时,剩余2个匹配;4个被匹配时,剩余1个;5个被匹配时,剩余0个。刚好与表格相吻合。
所以构出图来,跑一遍带花树求最大匹配即可。
最后答案就是最大匹配-n。
时间复杂度:
SRC
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std ;#define N 1000 + 10#define M 400000 + 10int vis[N] , fa[N] ;int Node[M] , Next[M] , Head[N] , tot = 0 ;int Pair[N] , Ord[N] , Pre[N] , D[N] ;int Case , n , m , ans ;int l , r ;void link( int u , int v ) { Node[++tot] = v ; Next[tot] = Head[u] ; Head[u] = tot ;}int Get( int x ) { return fa[x] == x ? x : fa[x] = Get(fa[x]) ; }int LCA( int x , int y ) { x = Get(x) , y = Get(y) ; vis[0] ++ ; while ( 1 ) { if ( x ) { if ( vis[x] == vis[0] ) return x ; vis[x] = vis[0] ; x = Get(Pre[Pair[x]]) ; } swap( x , y ) ; }}void Merge( int u , int v , int F ) { while ( Get(u) != F ) { Pre[u] = v ; if ( fa[u] == u ) fa[u] = F ; v = Pair[u] ; if ( Ord[v] == 1 ) { D[++r] = v ; Ord[v] = 0 ; } if ( fa[v] == v ) fa[v] = F ; u = Pre[v] ; }}int Blossom( int st ) { for (int i = 1 ; i <= n ; i ++ ) fa[i] = i , Ord[i] = -1 ; l = 0 , r = 1 ; D[1] = st ; Ord[st] = 0 ; while ( l < r ) { l ++ ; int now = D[l] ; for (int p = Head[now] ; p ; p = Next[p] ) { int nex = Node[p] ; if ( Ord[nex] < 0 ) { Ord[nex] = 1 ; Pre[nex] = now ; if ( !Pair[nex] ) { int a = now , b = nex ; while ( a ) { int t = Pair[a] ; Pair[a] = b ; Pair[b] = a ; b = t ; a = Pre[b] ; } return 1 ; } D[++r] = Pair[nex] ; Ord[Pair[nex]] = 0 ; } else { if ( Ord[nex] == 0 && Get(now) != Get(nex) ) { int L = LCA( now , nex ) ; Merge( now , nex , L ) ; Merge( nex , now , L ) ; } } } } return 0 ;}int main() { freopen( "fortress.in" , "r" , stdin ) ; freopen( "fortress.out" , "w" , stdout ) ; scanf( "%d" , &Case) ; while ( Case -- ) { tot = ans = 0 ; memset( Head , 0 , sizeof(Head) ) ; memset( vis , 0 , sizeof(vis) ) ; memset( Pair , 0 , sizeof(Pair) ) ; scanf( "%d%d" , &n , &m ) ; for (int i = 1 ; i <= m ; i ++ ) { int now = 7 * (i - 1) + 1 ; for (int j = now ; j <= now + 3 ; j ++ ) link( j , j + 1 ) , link( j + 1 , j ) ; link( now + 4 , now ) , link( now , now + 4 ) ; for (int j = now ; j <= now + 4 ; j ++ ) { link( now + 5 , j ) , link( j , now + 5 ) ; link( now + 6 , j ) , link( j , now + 6 ) ; } } for (int i = 1 ; i <= n ; i ++ ) { int k , now = i + 7 * m ; scanf( "%d" , &k ) ; for (int j = 1 ; j <= k ; j ++ ) { int x ; scanf( "%d" , &x ) ; for (int j = 7 * (x - 1) + 1 ; j <= 7 * (x - 1) + 5 ; j ++ ) link( now , j ) , link( j , now ) ; } } ans -= n ; n += 7 * m ; for (int i = 1 ; i <= n ; i ++ ) { if ( Pair[i] ) continue ; ans += Blossom(i) ; } printf( "%d\n" , ans ) ; } return 0 ;}
以上.
1 0
- JZOJ5004. Fortress
- 矮人要塞 dwarf fortress
- Database As a Fortress
- 堡垒(fortress)
- task1 T3 fortress
- Fake endorsement Obama fortress machine
- insist fortress g55 机械键盘"得救了"
- 【Shader拓展】Illustrative Rendering in Team Fortress 2
- URAL 1643 Attack of the Dark Fortress BFS
- URAL 1643 Attack of the Dark Fortress (BFS)
- Sun 发布 Fortress语言- 下一代并行计算语言(转自www.matrix.org.cn,作者chirs)
- Macvim最最最基本的使用
- 基础练习 01字串
- 【程序29】 题目:求一个3*3矩阵对角线元素之和
- java_猜数游戏
- 摘:一些面试 java
- JZOJ5004. Fortress
- struts2中struts.xml配置文件详解
- Oracle之Dblink
- Android Studio代码提示快捷键
- 关于支付宝即时到帐异步通知(notify_url)一点总结
- 阿里17在线编程测验
- 吐槽一下PopupWindow
- 2017.3.14 游戏(scoi2009) 失败总结
- (Android APP)HTTP调试代理之Fiddler抓包