Description
Have \ (n\) skills, each time through a wizard, a skill can be turned into another skill, ask most how many different skills.
Sol
Network flow.
First of all, the very naive I started, the skill will be split, the middle plus a list of wizards, \ (s\) to the initial skills of the number of edge capacity, the corresponding point between the capacity of the inf\, and then from the point to \ (t\) to the edge, the capacity is \ (1\), the wizard from the left side of a point to the right even a point, Capacity is \ (1\).
However this can be over most of the points ... Data good weak ...
In fact, it is wrong to build the map ... I'm thinking of using the maximum flow to represent a situation, but one less consideration is that the wizard can continue to change after one skill has been replaced by another.
In fact, it is not necessary to dismantle the point, directly connected to the wizard, and then directly from the wizard to connect back to it ...
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=getch AR (); 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;}
Hackerrank Training-the-army