• A Plug for UNIX POJ


    题意:

    几种插头,每一种都只有一个,但有无限个插头转换器,转换器(a,b) 意味着 可以把b转换为a,有几个设备,每个设备对应一种插头,求所不能匹配插头的设备数量

    这个题可以用二分图做 , 我用的是最大流,最后用设备数 减去 最大匹配数即可

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <queue>
    #define mem(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int maxn = 100100, INF = 0x7fffffff;
    int  head[maxn], d[maxn], cur[maxn];
    int n, m, s, t, z;
    int cnt;
    map<string, int> mapp;
    struct node{
        int u, v, c, next;
    }Node[maxn*4];
    
    void  add_(int u, int v, int c)
    {
        Node[cnt].u = u;
        Node[cnt].v = v;
        Node[cnt].c = c;
        Node[cnt].next = head[u];
        head[u] = cnt++;
    }
    
    void add(int u, int v, int c)
    {
        add_(u, v, c);
        add_(v, u, 0);
    }
    
    bool bfs()
    {
        queue<int> Q;
        mem(d, 0);
        Q.push(s);
        d[s] = 1;
        while(!Q.empty())
        {
            int u = Q.front(); Q.pop();
            for(int i=head[u]; i!=-1; i=Node[i].next)
            {
                node e = Node[i];
                if(!d[e.v]  && e.c > 0)
                {
                    d[e.v] = d[e.u] + 1;
                    Q.push(e.v);
                //    cout<< u << "   " << e.v << "   " << t <<endl;
                    if(e.v == t) break;
                }
            }
        }
        return d[t] != 0;
    }
    
    int dfs(int u, int cap)
    {
     //   cout<< cap <<endl;
        if(u == t || cap == 0)
            return cap;
        int ret = 0;
        for(int &i=cur[u]; i!=-1; i=Node[i].next)
        {
            node e = Node[i];
            if(d[e.v] == d[e.u] + 1 && e.c > 0)
            {
                int V = dfs(e.v, min(cap, e.c));
                Node[i].c -= V;
                Node[i^1].c += V;
                cap -= V;
                ret += V;
              //  cout<< V <<endl;
                if(cap == 0) break;
            }
        }
        return ret;
    }
    
    int dinic()
    {
        int ans = 0;
        while(bfs())
        {
            memcpy(cur, head, sizeof(head));
            ans += dfs(s, INF);
         //   cout<< ans <<endl;
        }
        return ans;
    }
    int  main()
    {
        cin>> n;
        mem(head, -1);
        s = 0, t = n + 3*m + 2*z + 10;
        for(int i=1; i<=n; i++)
        {
            string str;
            cin>> str;
            mapp[str] = i;
            add(s, i, 1);
        }
        cin>> m;
        for(int i=1; i<=m; i++)
        {
            string str, sstr;
            cin>> str >> sstr;
            add(n+i, n+m+i, 1);
            add(n+m+i, t, INF);
            if(!mapp[sstr])
            {
                mapp[sstr] = n + m*2 + i;
            }
            add(mapp[sstr], n+i, INF);
        }
        cin>> z;
        for(int i=1; i<=z; i++)
        {
            string u, v;
            cin>> u >> v;
            if(!mapp[u])
                mapp[u] = n+3*m+i;
            if(!mapp[v])
                mapp[v] = n+3*m+z+i;
      //     add(s, mapp[v], INF);
            add(mapp[v], mapp[u], INF);
        }
     //   cout<< m <<  "  " <<dinic() <<endl;
        cout<< m - dinic() <<endl;
    
        return 0;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    访存模型
    Petri网
    Forward secrecy
    TensorFlow训练神经网络cost一直为0
    解决tensorflow在训练的时候权重是nan问题
    tf.argmax
    Keras教程
    z-score
    隐马尔可夫(HMM)、前/后向算法、Viterbi算法
    受限玻尔兹曼机基础教程
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9225238.html
Copyright © 2020-2023  润新知