kuangbin專題專題十一 網絡流 POJ 1087 A Plug for UNIX

題目連接:https://vjudge.net/problem/POJ-1087node

題目:有n個插座,插座上只有一個插孔,有m個用電器,每一個用電器都有插頭,它們的插頭能夠同樣,ios

有k個插孔轉化器, a b 的意思就是  能夠把 b類的插孔變成a類的插孔,那麼a類對於的插頭就能夠用這個插孔充電了。ui

問:沒插孔的用電器最少有幾個。spa

思路:源點->插座->用電器->匯點。.net

由於插座之間能夠相互轉化,可能A,B,C,D均可以變成E類的插座,因此插座之間的流應該爲INF,其餘的邊流都是1,起到限流的做用。code

編號比較麻煩,能夠用map進行標記,編號。blog

這裏N = 1100 ,以前寫的代碼N = 410,wa了  而後我N  = 1100的過了以後,wa的代碼直接複製提交到POJ竟然過了。。。我是矇蔽的,很無奈。get

#include <iostream>
#include <cstdio>
#include <map>
#include <string>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;

const int N = 1100,INF = (int)1e9;
int id,tot,s,t,all;
int head[N],lev[N],cur[N];
map<string,int > mp;
vector<string > ve[2];
queue<int > que;
struct node{
    int to,nxt,flow;
}e[N*N];

inline void add(int u,int v,int flow){
    e[tot].to = v;
    e[tot].flow = flow;
    e[tot].nxt = head[u];
    head[u] = tot++;
    e[tot].to = u;
    e[tot].flow = 0;
    e[tot].nxt = head[v];
    head[v] = tot++;
}

inline bool ID(char* name){
    if(mp.count(name)) return true;
    else return false;
}

void build_map(){
    for(int i = 0; i <= 1000; ++i) head[i] = -1; tot = 0;
    int n,m,k;
    char name1[30],name2[30];
    scanf("%d",&n);

    for(int i = 1; i <= n; ++i){
        scanf("%s",name1);
        if(!ID(name1)) mp[name1] = ++id;
        ve[0].push_back(name1);
    }
    //插座到用電器
    scanf("%d",&m); all = m;
    for(int i = 1; i <= m; ++i){
        scanf("%s%s",name1,name2);
        if(!ID(name1)) mp[name1] = ++id;
        if(!ID(name2)) mp[name2] = ++id;
        add(mp[name2],mp[name1],1);
        ve[1].push_back(name1);
    }
    //插座之間
    scanf("%d",&k);
    for(int i = 1; i <= k; ++i){
        scanf("%s%s",name1,name2);
        if(!ID(name1)) mp[name1] = ++id;
        if(!ID(name2)) mp[name2] = ++id;
        add(mp[name2],mp[name1],INF);
    }
    //源點到插座
    s = 0, t = ++id;
    int num[2] = {ve[0].size(), ve[1].size()};
    for(int i = 0; i < num[0]; ++i){
        add(s,mp[ve[0][i]],1);
    }
    //用電器到匯點
    for(int i = 0; i < num[1]; ++i){
        add(mp[ve[1][i]],t,1);
    }
}

void show(){
    cout << "id  ====== " << id << endl;
    for(int i = 0; i <= id; ++i){
        printf("當前點爲 %d 相關聯的點:",i);
        for(int o = head[i]; ~o; o = e[o].nxt){
            printf("%d 流量爲 %d  ",e[o].to,e[o].flow);
        }cout << endl;
    }
}

bool bfs(int s,int t){
    for(int i = s; i <= t; ++i) lev[i] = 0;
    while(!que.empty()) que.pop();
    lev[s] = 1;
    que.push(s);
    while(!que.empty()){
        int u = que.front(); que.pop();
        for(int o = head[u]; ~o; o = e[o].nxt){
            int v = e[o].to;
            if(!lev[v] && e[o].flow){
                lev[v] = lev[u] + 1;
                if(v == t) return true;
                que.push(v);
            }
        }
    }
    return false;
}

int dfs(int now,int flow,int t){
    if(now == t) return flow;
    int sum = 0,tmp;
    for(int o = cur[now]; ~o; o = e[o].nxt){
        int to = e[o].to;
        if((lev[to] == lev[now] +1) && e[o].flow && (tmp = dfs(to,min(flow-sum,e[o].flow),t))){
            e[o].flow -= tmp;
            e[o^1].flow += tmp;
            if((sum += tmp) == flow) return sum;
        }
    }
    return sum;
}

int mf(int s,int t){
    int _mf = 0;
    while(bfs(s,t)){
        for(int i = s; i <= t; ++i) cur[i] = head[i];
        _mf += dfs(s,INF,t);
    }
    return _mf;
}

int main(){

    build_map();
  //  show();
    int _mf = mf(s,t);
    printf("%d\n",all -_mf);

    return 0;
}
相關文章
相關標籤/搜索