POJ1087 A Plug for UNIX

来源:互联网 发布:小米电视连接网络 编辑:程序博客网 时间:2024/05/12 02:02

一.原题链接:http://poj.org/problem?id=1087

二,题目大意:先给出N个插头,再给出M个需要插的电器,再给出k个可以转换的途径(注意可以无限次转换)。求最少剩下几个插头?

三,思路:源点和需要的插的电器所需插头相连,容量为各自出现次数,汇点和给出的插头相连,容量为各自出现的次数,之间转换的途径再相连,容量为无穷大,因为可以转换无限次。

四,代码:

#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <vector>#include <string>using namespace std;const int INF = 0x3f3f3f3f,          MAX_SIZE = 402;int s, t, maxFlow, nodeNum, cntT[MAX_SIZE], cntS[MAX_SIZE],    RE[MAX_SIZE][MAX_SIZE], H[MAX_SIZE], EF[MAX_SIZE];queue <int> que;char receptacles[MAX_SIZE][26];void init(){    int i, j;    maxFlow = 0;    s = nodeNum+1, t = nodeNum+2;    H[s] = nodeNum+2;    EF[s] = INF;    EF[t] = -INF;    for(i = 1; i <= nodeNum; i++)        RE[s][i] = cntS[i];    for(i = 1; i <= nodeNum; i++)        RE[i][t] = cntT[i];}void Push(int cur){    int i, temp;    for(i = 1; i <= t; i++){        temp = min(RE[cur][i], EF[cur]);        if(temp > 0 && (cur == s || H[cur] - H[i] == 1)){            RE[cur][i] -= temp; RE[i][cur] += temp;            EF[cur] -= temp; EF[i] += temp;            if(i == t)                maxFlow += temp;            if(i != s && i != t){                que.push(i);            }        }    }}void Relabel(int cur){    if(cur != s && cur != t && EF[cur] > 0){        H[cur]++;        que.push(cur);    }}void Push_Relabel(int m){    init();    int cur;    que.push(s);    while(!que.empty()){        cur = que.front();        que.pop();        Push(cur);        Relabel(cur);    }    printf("%d\n", m - maxFlow);}int Hash(char *buffer){    int i;    for(i = 1; i <= nodeNum; i++)        if(!strcmp(buffer, receptacles[i]))            return i;    nodeNum++;    strcpy(receptacles[nodeNum], buffer);    return nodeNum;}int main(){    //freopen("in.txt", "r", stdin);    //freopen("out.txt", "w", stdout);    int u, v, i, j, n, m, k, saveM;    char buffer1[26], buffer2[26];    scanf("%d", &n);    while(n--){        scanf("%s", buffer1);        cntT[Hash(buffer1)]++;    }    scanf("%d", &m);    saveM = m;    while(m--){        scanf("%s %s", buffer2, buffer1);        cntS[Hash(buffer1)]++;    }    scanf("%d", &k);    while(k--){        scanf("%s %s", buffer1, buffer2);        u = Hash(buffer1);        t = Hash(buffer2);        RE[u][t] = INF;    }    Push_Relabel(saveM);}


0 0