POJ 1087 A Plug for UNIX (最大流)

坑点:

  1. 注意虽然设备没有重复的名字,但是插座会有。
  2. 注意转换器的种类是k,个数无限。同时还得注意转换器是单向的。。。
  3. 然后就是自己的问题了。。我的isap模板没有考虑gap全是0的情况。所以碰到完全不连通的图就gg了。。(t了)
  4. cin关了同步还是很强大的。(虽然队友说有的题还是会卡cin。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#define inf 0x3f3f3f3f
typedef long long int lli;
using namespace std;
const lli maxn = 10000;
struct edge{
    lli to,v,next;
}ed[maxn+2000000];
lli d[maxn],cur[maxn],pre[maxn],gap[maxn],q[maxn+2000],cnte,head[maxn];
void ae(lli x, lli y, lli v) {
    ed[cnte].to = y;
    ed[cnte].v = v;
    ed[cnte].next = head[x];
    head[x] = cnte++;

    ed[cnte].to = x;
    ed[cnte].v = 0;
    ed[cnte].next = head[y];
    head[y] = cnte++;
}
void rbfs (lli s,lli t) {
    lli fi,se;
    memset(gap,0,sizeof(gap));
    memset(d,-1,sizeof(d));
    d[t] = 0;
    gap[0] = 1;
    fi = se = 0;
    q[se++] = t;
    while (fi != se) {
        lli u = q[fi++];
        for (lli i=head[u];~i;i=ed[i].next) {
            lli v = ed[i].to;
            if (~d[v]) continue;
            d[v] = d[u] + 1;
            q[se++] = v;
            gap[d[v]]++;
        }
    }
}
lli isap(lli s,lli t){
    memcpy(cur,head,sizeof(head));
    rbfs (s,t);
    lli flow = 0, u = pre[s]=s,i;
    while(d[t] < t+1) {
        if(u==t) {
            lli f = inf,neck;
            for(i= s;i != t;i = ed[cur[i]].to){
                if(f > ed[cur[i]].v){
                    f = ed[cur[i]].v;
                    neck = i;
                }
            }
            for(i = s;i != t;i = ed[cur[i]].to){
                ed[cur[i]].v -= f;
                ed[cur[i]^1].v += f;
            }
            flow += f;
            u = neck;
        }
        for(i = cur[u];~i;i=ed[i].next) if(d[ed[i].to]+1 == d[u] && ed[i].v) break;
        if(~i) {
            cur[u] = i;
            pre[ed[i].to] = u;
            u = ed[i].to;
        }
        else{
            if(gap[d[u]] == 0 || 0 == (--gap[d[u]])) break;
            lli mind = t+1;
            for(i = head[u];~i;i = ed[i].next){
                if(ed[i].v && mind > d[ed[i].to]){
                    cur[u] = i;
                    mind = d[ed[i].to];
                }
            }
            d[u] = mind + 1;
            gap[d[u]]++;
            u = pre[u];
        }
    }
    return flow;
}
void ini(){
    memset(head,-1,sizeof(head));cnte = 0;
}

string con,ele;
int cntcon[101000];
map<string,int> m1,m2;

int main(){
    std::ios::sync_with_stdio(false);
    ini();
    lli n,m,k;
    int cnt = 0;
    cin>>n;
    for(int i = 1;i <= n;i++){
        cin>>con;
        if(m1[con] == 0){
            m1[con] = ++cnt;
        }
        cntcon[ m1[con] ]++;
    }
    cin>>m;
    for(int i = 1;i <= m;i++){
        cin>>ele>>con;
        m2[ele] = i;
        if(m1[con] == 0){
            m1[con] = ++cnt;
        }
        ae(i,m1[con]+m,1);
    }
    cin>>k;
    for(int i = 1;i <= k;i++){
        cin>>ele>>con;
        if(m1[ele] == 0){
            m1[ele] = ++cnt;
        }
        if(m1[con] == 0){
            m1[con] = ++cnt;
        }
        ae(m1[ele]+m,m1[con]+m,inf);
    }
    int s = 0,t = m+cnt+1;
    for(int i = 1;i <= m;i++){
        ae(s,i,1);
    }
    for(int i = 1;i <= n;i++){
        ae(m+i,t,cntcon[i]);
    }
    cout<<m-isap(s,t)<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值