Description

有 \(n\) 个技能,每次可以通过一个巫师,将一个技能转化成另一个技能,问最有最多有多少不同的技能.

Sol

网络流.

先说说我一开始非常 naive 的建图,将技能拆点,中间加一列巫师, \(S\) 向初始技能连边容量为个数,对应点之间连边容量为 \(INF\),然后从拆出来的点向 \(T\) 连边,容量为 \(1\) ,巫师从左边连一个点右边连一个点,容量为 \(1\).

然而这样可以过大部分的点...数据好弱...

其实这样建图是错的...我是想着用最大流表示一种情况,但是少考虑了一种情况就是巫师将一个技能换成另一个技能之后还可以继续变换.

这样其实就不用拆点,直接连巫师,然后从巫师直接连回去就可以了...

Code

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<vector>
  4. #include<queue>
  5. #include<iostream>
  6. using namespace std;
  7.  
  8. const int N = 555;
  9.  
  10. inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
  11. while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; }
  12.  
  13. struct NetWork{
  14. struct Edge{ int fr,to,flow; };
  15. vector<Edge> edge;
  16. vector<int> g[N];
  17. int p[N],cur[N],d[N],a[N],aa[N],w[N];
  18. int s,t,m,n,k,flow,cp;
  19.  
  20. void Add_Edge(int fr,int to,int fl){
  21. edge.push_back((Edge){ fr,to,fl }),edge.push_back((Edge){ to,fr,0 });
  22. m=edge.size(),g[fr].push_back(m-2),g[to].push_back(m-1);
  23. }
  24. int BFS(){
  25. memset(d,0,sizeof(d));d[s]=1;
  26. queue<int> q;q.push(s);
  27. for(int x;!q.empty();){
  28. x=q.front(),q.pop();
  29. for(int i=0,v;i<g[x].size();i++) if(!d[v=edge[g[x][i]].to] && edge[g[x][i]].flow>0)
  30. d[v]=d[x]+1,q.push(v);
  31. }return d[t]>0;
  32. }
  33. int Dinic(){
  34. flow=0;
  35. for(int x,k,mine,minf;BFS();){
  36. for(memset(cur,0,sizeof(cur)),k=0,x=s;;){
  37. if(x==t){
  38. mine=-1,minf=0x7fffffff;
  39. for(int i=0;i<k;i++) if(edge[p[i]].flow < minf) minf=edge[p[i]].flow,mine=i;
  40. for(int i=0;i<k;i++) edge[p[i]].flow-=minf,edge[p[i]^1].flow+=minf;
  41. k=mine,flow+=minf,x=edge[p[mine]].fr;
  42. }
  43. for(int &i=cur[x];i<g[x].size();i++){
  44. Edge &e=edge[g[x][i]];
  45. if(e.flow>0 && d[x]+1==d[e.to]) break;
  46. }
  47. if(cur[x]<g[x].size()){
  48. p[k]=g[x][cur[x]],x=edge[p[k++]].to;
  49. }else{
  50. if(!k) break;
  51. d[x]=-1,x=edge[p[--k]].fr;
  52. }
  53. }
  54. }return flow;
  55. }
  56. void init(){
  57. n=in(),k=in();
  58. s=n+k+1,t=s+1;
  59. for(int i=1,x;i<=n;i++) x=in(),Add_Edge(s,i,x),Add_Edge(i,t,1);
  60. for(int i=1,x,y;i<=k;i++){
  61. x=in();
  62. for(int j=1,tmp;j<=x;j++) tmp=in(),Add_Edge(tmp,n+i,1);
  63. y=in();
  64. for(int j=1,tmp;j<=y;j++) tmp=in(),Add_Edge(n+i,tmp,1);
  65. }
  66. cout<<Dinic()<<endl;
  67. }
  68. }sol;
  69.  
  70. int main(){
  71. sol.init();
  72. return 0;
  73. }

  

HackerRank training-the-army的更多相关文章

  1. HackerRank "Training the army" - Max Flow

    First problem to learn Max Flow. Ford-Fulkerson is a group of algorithms - Dinic is one of it.It is ...

  2. 2019 Multi-University Training Contest 2 - 1008 - Harmonious Army - 最大流

    http://acm.hdu.edu.cn/showproblem.php?pid=6598 一开始就觉得是网络流,但是一直都不会怎么建图. 这里要考虑. 每一组边(u,v,a,b,c)建立如下的连接 ...

  3. 2019 Multi-University Training Contest 2 Harmonious Army(最小割)

    题意:给你n个点 每个点都有两种选择 成为战士或者法师 现在给你m个关系 对应这两个人的对应关系的权值A,B,C 思路:按照下面的思路建图跑最小割(要注意权值要乘2 可能存在不整除的情况) #incl ...

  4. Gym - 100283F F. Bakkar In The Army —— 二分

    题目链接:http://codeforces.com/gym/100283/problem/F F. Bakkar In The Army time limit per test 2 seconds ...

  5. 2019 Multi-University Training Contest 2

    2019 Multi-University Training Contest 2 A. Another Chess Problem B. Beauty Of Unimodal Sequence 题意 ...

  6. HDU校赛 | 2019 Multi-University Training Contest 2

    2019 Multi-University Training Contest 2 http://acm.hdu.edu.cn/contests/contest_show.php?cid=849 100 ...

  7. hdu 4946 2014 Multi-University Training Contest 8

    Area of Mushroom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  8. 2016 Multi-University Training Contests

    2016 Multi-University Training Contest 1 2016 Multi-University Training Contest 2 2016 Multi-Univers ...

  9. 2016 Multi-University Training Contest 2 D. Differencia

    Differencia Time Limit: 10000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  10. 2016 Multi-University Training Contest 1 G. Rigid Frameworks

    Rigid Frameworks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

随机推荐

  1. 自然语言19.1_Lemmatizing with NLTK(单词变体还原)

    QQ:231469242 欢迎喜欢nltk朋友交流 https://www.pythonprogramming.net/lemmatizing-nltk-tutorial/?completed=/na ...

  2. ansible执行playbook时间显示的python脚本

    import datetime import os import time from ansible.plugins.callback import CallbackBase class Callba ...

  3. CentOS6.5个人目录下中文路径转英文路径

    如果安装了中文版到CentOS之后,root目录及home目录下会出现中文到路径名,如“桌面”.“文档”,“图片 .公共的” .“下载”. “音乐”.“ 视频”等目录,这样在命令行上操作十分到不方便. ...

  4. thinkphp 模板里a标签 href 带参数的 使用U函数方法

    简单的说就是模板里 分类的链接地址 实现这个样子的 <a href="/index.php/Home/Category/assortment/cateid/2.html"&g ...

  5. YII2 自定义日志路径

    YII 提供的日志写入方法: 1.Yii::getLogger()->log($message, $level, $category = 'application') 2.Yii::trace( ...

  6. mysql 数据表中查找、删除重复记录

    为了性能考虑,在阅读之前提醒大家,如果有子查询,子查询查询到的数据最好不要超过总数据量的30%. 查询有重复数据的记录 select * from F group by a,b,c,d having ...

  7. 解决前面有一篇文章中'flashplayer.so为什么要设置777权限的'问题 的 思考了

    列出某个目录下的所有内容? ls -A, -A等同于-a, 即是-all, 只是-A 不显示.和.. ll ls 某个目录, 如果它下面没有任何东西, 那么 就没有输出! 同时, ll某个目录, 不会 ...

  8. oracle 中的Ipad()函数

    本文基于转载: lpad函数从左边对字符串使用指定的字符进行填充.lpad意思是从左边填充的意思. 语法格式如下: lpad( string, padded_length, [ pad_string ...

  9. LINUX下搭建VPN

    一.准备 需要 dkms-2.0.17.5-1.noarch.rpm.ppp-2.4.5-33.0.rhel6.x86_64.rpm.pptpd-1.4.0-1.el6.x86_64.rpm,并依次安 ...

  10. H5移动端知识点总结

    H5移动端知识点总结 阅读目录 移动开发基本知识点 calc基本用法 box-sizing的理解及使用 理解display:box的布局 理解flex布局 Flex布局兼容知识点总结 回到顶部 移动开 ...