Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define pb push_back
- #define N 15
- #define ll long long
- using namespace std;
- int A[ N+5 ];
- map< string , int> M;
- vector<int>adj[ N+5 ];
- string s,cad;
- int n , m ,edges, caso=1;
- ll maxi ;
- struct flow_graph{
- int MAX_V,E,s,t,head,tail;
- int *cap,*to,*next,*last,*dist,*q,*now;
- flow_graph(){}
- flow_graph(int V, int MAX_E){
- MAX_V = V; E = 0;
- cap = new int[2*MAX_E], to = new int[2*MAX_E], next = new int[2*MAX_E];
- last = new int[MAX_V], q = new int[MAX_V];
- dist = new int[MAX_V], now = new int[MAX_V];
- fill(last,last+MAX_V,-1);
- }
- void clear(){
- fill(last,last+MAX_V,-1);
- E = 0;
- }
- void add_edge(int u, int v, int uv){
- to[E] = v, cap[E] = uv, next[E] = last[u]; last[u] = E++;
- to[E] = u, cap[E] = 0, next[E] = last[v]; last[v] = E++;
- }
- bool bfs(){
- fill(dist,dist+MAX_V,-1);
- head = tail = 0;
- q[tail] = t; ++tail;
- dist[t] = 0;
- while(head<tail){
- int v = q[head]; ++head;
- for(int e = last[v];e!=-1;e = next[e]){
- if(cap[e^1]>0 && dist[to[e]]==-1){
- q[tail] = to[e]; ++tail;
- dist[to[e]] = dist[v]+1;
- }
- }
- }
- return dist[s]!=-1;
- }
- int dfs(int v, int f){
- if(v==t) return f;
- for(int &e = now[v];e!=-1;e = next[e]){
- if(cap[e]>0 && dist[to[e]]==dist[v]-1){
- int ret = dfs(to[e],min(f,cap[e]));
- if(ret>0){
- cap[e] -= ret;
- cap[e^1] += ret;
- return ret;
- }
- }
- }
- return 0;
- }
- long long max_flow(int source, int sink){
- s = source; t = sink;
- long long f = 0,df;
- while(bfs()){
- for(int i = 0;i<MAX_V;++i) now[i] = last[i];
- while(true){
- df = dfs(s,INT_MAX);
- if(df==0) break;
- f += df;
- }
- }
- return f;
- }
- }G;
- void calc( ){
- int S =n+m , T = n+m+1;
- for( int mask=1 ; mask<( 1<<n ) ; ++mask ){
- int bits = __builtin_popcount( mask );
- if( bits < maxi ) continue;
- int need=0;
- for( int i =0 ;i<n ; ++i ){
- if( ! ( mask & ( 1<<i ) ) ) continue;
- else need+=A[ i ];
- }
- G = flow_graph( n+m+5 , edges + n + m +5 );
- for( int i =0 ; i<n ; ++i ){
- if( ! ( mask & ( 1<<i ) ) ) continue;
- int sz = adj[ i ].size( );
- for( int j =0 ; j<sz ; ++j ){
- int v = adj[ i ][ j ];
- G.add_edge( v , i , 1 );
- }
- }
- for( int i=0 ; i<m ; ++i ){
- G.add_edge( S , i , 1 );
- }
- for( int i=0 ; i<n ; ++i ){
- G.add_edge( i+m , T , A[ i ] );
- }
- ll res = G.max_flow( S, T );
- if( res == need ){
- maxi = max( maxi, res );
- }
- }
- }
- bool doit(){
- scanf("%d%d",&n ,&m );
- if( !n && !m )return 0;
- edges = 0;
- for( int i=0 ; i<n ; ++i ){
- cin>>s>>A[ i ];
- M[ s ] = i+m; // contests
- }
- getline( cin , cad );
- for( int i =0 ; i<m ; ++i ){
- getline( cin , cad );
- istringstream in( cad );
- while( in >>s ){
- adj[ i ].pb( M[ cad ] );
- edges++;
- }
- }
- maxi = 0;
- calc( );
- printf("Case #%d: %lld\n", caso++ , maxi );
- return 1;
- }
- int main( ){
- while( doit());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement