1. 程式人生 > >2018icpc南京現場賽-I Magic Potion(最大流)

2018icpc南京現場賽-I Magic Potion(最大流)

題意:

n個英雄,m個怪獸,第i個英雄可以打第i個集合裡的怪獸,一個怪獸可以在多個集合裡

有k瓶藥水,每個英雄最多喝一次,可以多打一隻怪獸,求最多打多少隻

n,m,k<=500

思路:

最大流,建圖方式:

 

程式碼:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
//#include<stack>
#include<queue>
#include
<deque> #include<set> #include<vector> #include<map> #include<functional> #define fst first #define sc second #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define
rc root<<1|1 #define lowbit(x) ((x)&(-x)) using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const db eps = 1e-6; const int mod = 1e9+7; const
int maxn = 2e6+100; const int maxm = 2e6+100; const int inf = 0x3f3f3f3f; const db pi = acos(-1.0); int head[maxn],d[maxn];// int ver[maxm],edge[maxm],Next[maxm];//edge[i]: c for edge_i int n, m, s, t, tot, maxflow; queue<int>q; int vis[maxn];//出現過 void add(int x, int y, int z){ ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot; ver[++tot]=x,edge[tot]=0,Next[tot]=head[y],head[y]=tot; } bool bfs(){ mem(d,0); while(!q.empty())q.pop(); q.push(s); d[s]=1; while(!q.empty()){ int x = q.front(); q.pop(); for(int i = head[x]; i; i = Next[i]){ if(edge[i] && !d[ver[i]]){ q.push(ver[i]); d[ver[i]] = d[x] + 1; if(ver[i] == t) return true; } } } return false; } int dinic(int x, int flow){ if(x==t) return flow; int rest = flow, k; for(int i = head[x]; i; i = Next[i]){ if(edge[i] && d[ver[i]] == d[x]+1){ k = dinic(ver[i], min(rest, edge[i])); if(!k) d[ver[i]] = 0; edge[i] -= k; edge[i^1] += k; rest -= k; } } return flow - rest; } int main(){ int num; scanf("%d %d %d", &n, &m, &num); tot = 1; //scanf("%d %d", &s, &t); s = 1; t = n+m+3; add(s,2,num); for(int i = 1; i <= n; i++){ int sz, x; add(s,2+i,1); add(2,2+i,1); scanf("%d", &sz); for(int j = 1; j <= sz; j++){ scanf("%d", &x); add(2+i,2+n+x,1); } } for(int i = 1; i <= m; i++){ add(2+n+i,t,1); } int flow = 0; maxflow=0; while(bfs()){ while(1){ flow = dinic(s,inf); if(!flow)break; maxflow+=flow; } } printf("%d\n",maxflow); return 0; } /* 3 5 0 4 1 2 3 5 2 2 5 2 1 2 5 10 2 2 3 10 5 1 3 4 6 10 5 3 4 6 8 9 3 1 9 10 5 1 3 6 7 10 */