1. 程式人生 > >Gym - 101981I The 2018 ICPC Asia Nanjing Regional Contest I.Magic Potion 最大流

Gym - 101981I The 2018 ICPC Asia Nanjing Regional Contest I.Magic Potion 最大流

題面

題意:n個英雄,m個怪獸,第i個英雄可以打第i個集合裡的一個怪獸,一個怪獸可以在多個集合裡,有k瓶藥水,每個英雄最多喝一次,可以多打一隻怪獸,求最多打多少隻 n,m,k<=500

題解:顯然的最大流裸體,多加一個藥水點,藥醬入度k,然後再連向英雄

        隊友抄的模板所以不是我的那個板子

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 struct Edge
  4 {
  5     int from,to,cap,flow;
6 Edge(int u,int v,int c,int f) 7 { 8 from=u; 9 to=v; 10 cap=c; 11 flow=f; 12 } 13 }; 14 const int maxn=2050; 15 const int INF=0x3f3f3f3f; 16 struct Dinic 17 { 18 int n,m,s,t; 19 vector<Edge> edges; 20 vector<int
> G[maxn]; 21 int d[maxn]; 22 int cur[maxn]; 23 bool vis[maxn]; 24 void AddEdge(int from,int to, int cap) 25 { 26 edges.push_back(Edge(from,to,cap,0)); 27 edges.push_back(Edge(to,from,0,0)); 28 m=edges.size(); 29 G[from].push_back(m-2
); 30 G[to].push_back(m-1); 31 } 32 bool BFS() 33 { 34 memset(vis,0,sizeof(vis)); 35 queue<int> Q; 36 Q.push(s); 37 d[s]=0; 38 vis[s]=1; 39 while(!Q.empty()) 40 { 41 int x=Q.front(); 42 Q.pop(); 43 for(int i=0;i<G[x].size();i++) 44 { 45 Edge& e=edges[G[x][i]]; 46 if(!vis[e.to]&&e.cap>e.flow) 47 { 48 vis[e.to]=1; 49 d[e.to]=d[x]+1; 50 Q.push(e.to); 51 } 52 } 53 } 54 return vis[t]; 55 } 56 int DFS(int x,int a) 57 { 58 if(x==t||a==0) return a; 59 int flow=0,f; 60 for(int& i=cur[x];i<G[x].size();i++) 61 { 62 Edge& e=edges[G[x][i]]; 63 if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) 64 { 65 e.flow+=f; 66 edges[G[x][i]^1].flow-=f; 67 flow+=f; 68 a-=f; 69 if(a==0) break; 70 } 71 } 72 return flow; 73 } 74 int Maxflow(int s,int t) 75 { 76 this->s=s;this->t=t; 77 int flow=0; 78 while(BFS()) 79 { 80 memset(cur,0,sizeof(cur)); 81 flow+=DFS(s,INF); 82 } 83 return flow; 84 } 85 }fuck; 86 int main() 87 { 88 int n,m,k,i,j,tmpn,x; 89 scanf("%d%d%d",&n,&m,&k); 90 for(i=1;i<=n;i++) 91 { 92 fuck.AddEdge(0,i+1,1); 93 fuck.AddEdge(1,i+1,1); 94 } 95 fuck.AddEdge(0,1,k); 96 for(i=1;i<=n;i++) 97 { 98 scanf("%d",&tmpn); 99 for(j=1;j<=tmpn;j++) 100 { 101 scanf("%d",&x); 102 fuck.AddEdge(i+1,n+1+x,1); 103 } 104 } 105 for(i=1;i<=m;i++) 106 fuck.AddEdge(n+1+i,n+m+2,1); 107 printf("%d\n",fuck.Maxflow(0,n+m+2)); 108 return 0; 109 }