POJ-1087 A Plug for UNIX (Network Flow)

thinking

Electrical appliances 1-100, with 100 kinds of interfaces. Note: You notice that some of the devices use plugs for which there is no receptacle.

Wall interface 1 - 100, there are 1 - 100 transfer interface, transfer interface has two interfaces. Assuming that all interface types are different, there are 400 interfaces. So the sink value >= 501.

When reading into an electrical appliance, its interface may not be on the wall, so it is necessary to determine whether the interface has been labeled before.

When you read the interface, read the two interfaces first, then determine whether the label has been assigned. Finally, the INF interface is built between the interface ports and the interface ports at the interface port.

#include <iostream>
#include <stdio.h>
#include <map>
#include <queue>
#include <string>
#include <string.h>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=110;
map<string,int>rec,dev;
int dev_cnt=1,rec_cnt=101;
int n,m,k;

struct Edge {
    int to,cap,flow;
};

struct Dinic {
    int cnt,s,t;
    int head[6*maxn];
    int deep[6*maxn];
    int vis[6*maxn];
    int cur[6*maxn];
    int next[maxn*maxn*4];
    Edge edge[maxn*maxn*4];

    void addEdge(int u,int v,int w)
    {
        edge[cnt].to=v;
        edge[cnt].cap=w;
        edge[cnt].flow=0;
        next[cnt]=head[u];
        head[u]=cnt++;

        edge[cnt].to=u;
        edge[cnt].cap=0;
        edge[cnt].flow=0;
        next[cnt]=head[v];
        head[v]=cnt++;
    }

    void init()
    {
        memset(head,-1,sizeof(head));
        cnt=0;
        s=0;
        t=601;
    }

    bool bfs()
    {
        memset(vis,0,sizeof(vis));
        memset(deep,0,sizeof(deep));
        deep[s]=0;
        vis[s]=1;
        queue<int> q;
        q.push(s);
        while (!q.empty()) {
            int u=q.front();
            q.pop();
            for (int i=head[u];i!=-1;i=next[i]) {
                Edge &e=edge[i];
                if (!vis[e.to]&&e.cap>e.flow) {
                    vis[e.to]=1;
                    deep[e.to]=deep[u]+1;
                    q.push(e.to);
                }
            }
        }
        return vis[t];
    }

    int dfs(int u,int in)
    {
        if (in==0||u==t) {
            return in;
        }
        int f=0,out=0;
        for (int &i=cur[u];i!=-1;i=next[i]) {
            Edge &e=edge[i];
            if (deep[e.to]==deep[u]+1&&(f=dfs(e.to,min(in,e.cap-e.flow)))>0) {
                edge[i].flow+=f;
                edge[i^1].flow-=f;
                in-=f;
                out+=f;
                if (in==0) {
                    break;
                }
            }
        }
        return out;
    }

    int maxflow()
    {
        int ans=0;
        while (bfs()) {
            for (int i=0;i<6*maxn;i++) {
                cur[i]=head[i];
            }
            ans+=dfs(s,INF);
        }
        return ans;
    }

}DC;

int main()
{
    DC.init();
    cin>>n;
    string tmp;
    for (int i=0;i<n;i++) {
        cin>>tmp;
        rec[tmp]=rec_cnt;
        DC.addEdge(rec_cnt,601,1);
        rec_cnt++;
    }
    cin>>m;
    for (int i=0;i<m;i++) {
        cin>>tmp;
        dev[tmp]=dev_cnt;
        DC.addEdge(0,dev_cnt,1);
        cin>>tmp;
        if (rec[tmp]==0) {
            rec[tmp]=rec_cnt++;
        }
        DC.addEdge(dev_cnt,rec[tmp],1);
        dev_cnt++;
    }
    cin>>k;
    string in,out;
    for (int i=0;i<k;i++) {
        cin>>in;
        cin>>out;
        if (rec[in]==0) {
            rec[in]=rec_cnt++;
        }
        if (rec[out]==0) {
            rec[out]=rec_cnt++;
        }
        DC.addEdge(rec[in],rec[out],INF);
    }
    printf("%d\n",dev_cnt-1-DC.maxflow());
    return 0;
}

Posted by phpparty on Thu, 03 Oct 2019 08:56:17 -0700