zoukankan      html  css  js  c++  java
  • HackerRank training-the-army

    Description

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

    Sol

    网络流.

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

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

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

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

    Code

    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<iostream>
    using namespace std;
    
    const int N = 555;
    
    inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar();
    	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x; }
    
    struct NetWork{
    	struct Edge{ int fr,to,flow; };
    	vector<Edge> edge;
    	vector<int> g[N];
    	int p[N],cur[N],d[N],a[N],aa[N],w[N];
    	int s,t,m,n,k,flow,cp;
    	
    	void Add_Edge(int fr,int to,int fl){
    		edge.push_back((Edge){ fr,to,fl }),edge.push_back((Edge){ to,fr,0 });
    		m=edge.size(),g[fr].push_back(m-2),g[to].push_back(m-1);
    	}
    	int BFS(){
    		memset(d,0,sizeof(d));d[s]=1;
    		queue<int> q;q.push(s);
    		for(int x;!q.empty();){
    			x=q.front(),q.pop();
    			for(int i=0,v;i<g[x].size();i++) if(!d[v=edge[g[x][i]].to] && edge[g[x][i]].flow>0)
    				d[v]=d[x]+1,q.push(v);
    		}return d[t]>0;
    	}
    	int Dinic(){
    		flow=0;
    		for(int x,k,mine,minf;BFS();){
    			for(memset(cur,0,sizeof(cur)),k=0,x=s;;){
    				if(x==t){
    					mine=-1,minf=0x7fffffff;
    					for(int i=0;i<k;i++) if(edge[p[i]].flow < minf) minf=edge[p[i]].flow,mine=i;
    					for(int i=0;i<k;i++) edge[p[i]].flow-=minf,edge[p[i]^1].flow+=minf;
    					k=mine,flow+=minf,x=edge[p[mine]].fr;
    				}
    				for(int &i=cur[x];i<g[x].size();i++){
    					Edge &e=edge[g[x][i]];
    					if(e.flow>0 && d[x]+1==d[e.to]) break;
    				}
    				if(cur[x]<g[x].size()){
    					p[k]=g[x][cur[x]],x=edge[p[k++]].to;
    				}else{
    					if(!k) break;
    					d[x]=-1,x=edge[p[--k]].fr;
    				}
    			}
    		}return flow;
    	}
    	void init(){
    		n=in(),k=in();
    		s=n+k+1,t=s+1;
    		for(int i=1,x;i<=n;i++) x=in(),Add_Edge(s,i,x),Add_Edge(i,t,1);
    		for(int i=1,x,y;i<=k;i++){
    			x=in();
    			for(int j=1,tmp;j<=x;j++) tmp=in(),Add_Edge(tmp,n+i,1);
    			y=in();
    			for(int j=1,tmp;j<=y;j++) tmp=in(),Add_Edge(n+i,tmp,1);
    		}
    		cout<<Dinic()<<endl;
    	}
    }sol;
    
    int main(){
    	sol.init();
    	return 0;
    }
    

      

  • 相关阅读:
    PHP下安装memcached
    SQL Case when 的使用方法
    关于安装PHP补装PDO与PDO_MYSQL操作
    nginx 站点80跳443配置
    mysql 热备
    Ajax技术---核心XMLHttpRequest对象
    线性代数中一组基向量的标准正交化原理通熟易懂理解
    关于Quartus构建nios软核以及eclipse建立c语言工程以及成功下载到FPGA芯片过程遇到的各种问题以及解决方法详解
    ucosii操作系统内核源码学习第一篇
    Qt编译工程提示qt creator no rule to make target opencv2/core/hal/interface.h need by debug解决方法
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6030383.html
Copyright © 2011-2022 走看看