zoukankan      html  css  js  c++  java
  • kuangbin专题专题十一 网络流 POJ 1087 A Plug for UNIX

    题目链接:https://vjudge.net/problem/POJ-1087

    题目:有n个插座,插座上只有一个插孔,有m个用电器,每个用电器都有插头,它们的插头可以一样,

    有k个插孔转化器, a b 的意思就是  可以把 b类的插孔变成a类的插孔,那么a类对于的插头就可以用这个插孔充电了。

    问:没插孔的用电器最少有几个。

    思路:源点->插座->用电器->汇点。

    因为插座之间可以相互转化,可能A,B,C,D都可以变成E类的插座,所以插座之间的流应该为INF,其他的边流都是1,起到限流的作用。

    编号比较麻烦,可以用map进行标记,编号。

    这里N = 1100 ,之前写的代码N = 410,wa了  然后我N  = 1100的过了之后,wa的代码直接复制提交到POJ居然过了。。。我是蒙蔽的,很无奈。

    #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
    ",all -_mf);
    
        return 0;
    }
  • 相关阅读:
    snmp扫描
    操作系统扫描
    服务扫描
    端口扫描,僵尸机扫描
    主动信息收集:四层发现
    主动信息收集:三层发现
    主动信息收集:二层发现
    RECON-NG
    metadata信息的采集
    cupp字典生成器使用
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12243189.html
Copyright © 2011-2022 走看看