poj 1087 A Plug for UNIX isap

来源:互联网 发布:佛教的软件 编辑:程序博客网 时间:2024/06/06 20:11

经典网络流模型。

n种插座,m种电器和对应的插座,k种转换器(数量无限)(s1, s2表示s2插座可以转成s1插座)。

建超源超汇,超源和插座连,流量1,电器和插座连,流量1,然后插座和对应电器连边,流量1,最后是通过转换器的插座之间连边,流量是inf(因为转换器本身就是inf的)然后模板一套即可

#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <string>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1 | 1#define ls rt << 1#define rs rt << 1 | 1#define pi acos(-1.0)#define eps 1e-8typedef long long ll;const int inf = 0x3f3f3f3f;const int N = 110;const int st = 0, ed = (N * 8) - 10;struct node{    int v, w, nxt;}e[N*N];int head[N<<3];int pre[N<<3];int gap[N<<3];int cur[N<<3];int dep[N<<3];int s[N], top;int cnt, tot;int n, m, k;queue <int> q;map <string, int> mp;void init(){    mp.clear();    cnt = tot = 0;    memset( head, -1, sizeof( head ) );}void add( int u, int v, int w ){    e[cnt].v = v;    e[cnt].w = w;    e[cnt].nxt = head[u];    head[u] = cnt++;    e[cnt].w = 0;    e[cnt].v = u;    e[cnt].nxt = head[v];    head[v] = cnt++;}void rev_bfs(){    memset( gap, 0, sizeof( gap ) );    memset( dep, -1, sizeof( dep ) );    while( !q.empty() ) q.pop();    q.push(ed);    dep[ed] = 0;    gap[0] = 1;    while( !q.empty() ) {        int u = q.front();        q.pop();        for( int i = head[u]; ~i; i = e[i].nxt ) {            int v = e[i].v;            if( ~dep[v] )                continue;            dep[v] = dep[u] + 1;            gap[dep[v]]++;            q.push(v);        }    }}int isap(){    int flow = 0, u = st, i;    memcpy( cur, head, sizeof head );    rev_bfs();    top = 0;    int nv = ed + 1;    while( dep[st] < nv ) {        if( u == ed ) {            int tmp, minn = inf;            for( i = 0; i < top; ++i ) {                if( minn > e[s[i]].w ) {                    minn = e[s[i]].w;                    tmp = i;                }            }            for( i = 0; i < top; ++i ) {                e[s[i]].w -= minn;                e[s[i]^1].w += minn;            }            flow += minn;            top = tmp;            u = e[s[top]^1].v;        }        for( i = cur[u]; ~i; i = e[i].nxt ) {            if( e[i].w > 0 && dep[u] == dep[e[i].v] + 1 ) {                cur[u] = i;                break;            }        }        if( ~i ) {            s[top++] = cur[u];            u = e[i].v;        }        else {            if( 0 == gap[dep[u]] )                break;            int minn = nv;            for( i = head[u]; ~i; i = e[i].nxt ) {                int v = e[i].v;                if( e[i].w > 0 && minn > dep[v] ) {                    minn = dep[v];                    cur[u] = i;                }            }            dep[u] = minn + 1;            gap[dep[u]]++;            if( u != st ) {                u = e[ s[--top]^1 ].v;            }        }    }    return flow;}int main(){    while( cin >> n ) {        init();        string tmp, tmpp;        for( int i = 1; i <= n; ++i ) {            cin >> tmp;            mp[tmp] = ++tot;            add( st, mp[tmp], 1 );        }   //插座        int x = tot;        scanf("%d", &m);        int u, v;        for( int i = 1; i <= m; ++i ) {            cin >> tmp >> tmpp;            if( !mp[tmp] ) {                mp[tmp] = ++tot;                //add( mp[tmp], ed, 1 );            }            if( !mp[tmpp] ) {                mp[tmpp] = ++tot;                //add( st, mp[tmpp], 1 );            }            u = mp[tmp];            v = mp[tmpp];            add( v, u, 1 );            add( u, ed, 1 );        }   //插头        scanf("%d", &k);        for( int i = 1; i <= k; ++i ) {            cin >> tmp >> tmpp;            if( !mp[tmp] )                mp[tmp] = ++tot;            if( !mp[tmpp] )                mp[tmpp] = ++tot;            u = mp[tmp];            v = mp[tmpp];            add( v, u, inf );        }   //插座之间        int ans = isap();        printf("%d\n", m - ans);    }    return 0;}


0 0