【最大流】POJ-1087-A Plug for UNIX

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/monochrome00/article/details/81488095

 题目链接<http://poj.org/problem?id=1087>


题意:

有n个连接了电源的插座。m个设备,每个设备有对应的插头。有k个转换器,转换器能够让连接的插座进行转换,转换器无限个数。问最少有几个设备没法连接插座充电。


题解:

将每个插上电源的插座连接一个超级汇点,权值为1。

建一个超级源点连接每一个设备,权值为1。

设备与它对应的插头连接,权值为1。

转换器将两个插头连接,权值为无穷,因为转换器的个数是无穷。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <cmath>
#include <map>
using namespace std;
const int N=1e5+7;
const int inf=1e5+7;

struct Edge{
    int u,v,w,next;
    Edge(int u=0,int v=0,int w=0,int next=0):u(u),v(v),w(w),next(next){}
}edge[10*N];
int n,m,k,edn,sp,tp;
int p[N],d[N],c[N];

void add(int u,int v,int w){
    edge[edn]=Edge(u,v,w,p[u]);p[u]=edn++;
    edge[edn]=Edge(v,u,0,p[v]);p[v]=edn++;
}
bool bfs(){
    memset(d,-1,sizeof(d));d[sp]=0;
    queue<int>q;q.push(sp);
    while(!q.empty()){
        int u=q.front();
        q.pop();
        for(int i=p[u];~i;i=edge[i].next){
            int v=edge[i].v;
            if(d[v]==-1&&edge[i].w){
                d[v]=d[u]+1;
                q.push(v);
                if(v==tp) return true;
            }
        }
    }
    return ~d[tp];
}
int dfs(int u,int b){
    if(u==tp) return b;
    int r=0;
    for(int i=c[u];~i;i=edge[i].next){
        int v=edge[i].v;
        if(edge[i].w&&d[v]==d[u]+1){
            int x=min(edge[i].w,b-r);
            c[u]=i;
            x=dfs(v,x);
            r+=x;
            edge[i].w-=x;
            edge[i^1].w+=x;
            if(r==b) break;
        }
    }
    if(!r)d[u]=-2;
    return r;
}
int dinic(){
    int total=0,t;
    while(bfs()){
        memcpy(c,p,sizeof(p));
        while(t=dfs(sp,inf))
        total+=t;
    }
    return total;
}
string s;
map<string,int>a;
map<string,int>b;
int main()
{
    memset(p,-1,sizeof(p));edn=0;
    scanf("%d",&n);
    int toa=1,tob=200;
    sp=800,tp=sp+1;
    for(int i=1;i<=n;i++){
        cin>>s;
        if(!b[s]) b[s]=++tob;
        add(b[s],tp,1);
    }
    scanf("%d",&m);
    for(int i=1;i<=m;i++){
        cin>>s;
        if(!a[s]) a[s]=++toa;
        int u=a[s];
        cin>>s;
        if(!b[s]) b[s]=++tob;
        int v=b[s];
        add(u,v,1);
        add(sp,u,1);
    }
    scanf("%d",&k);
    for(int i=1;i<=k;i++){
        cin>>s;
        if(!b[s]) b[s]=++tob;
        int u=b[s];
        cin>>s;
        if(!b[s]) b[s]=++tob;
        int v=b[s];
        add(u,v,inf);
    }
    printf("%d\n",m-dinic());
}

猜你喜欢

转载自blog.csdn.net/monochrome00/article/details/81488095