• POJ1087 A Plug for UNIX(网络流)


    在会议开始之前,你收集所有记者想要使用的设备,并尝试设置它们。你注意到有些设备使用没有插座的插头。你想知道这些设备是否来自建造这个房间时并不存在的国家。对于一些插座,有几个设备使用相应的插头。对于其他插座,没有使用相应插头的设备。

    为了解决这个问题,你可以去附近的零件供应商店。该商店出售的适配器允许在不同类型的插座上使用一种类型的插头。此外,还允许将适配器插入到其他适配器中。该商店没有为所有可能的插头和插座组合提供适配器,但实际上他们有无限的供应。

    输入

    输入将包括一种情况。第一行包含一个正整数n (1 <= n <= 100),表示房间中插座的数量。接下来的n行列出了在房间中找到的容器类型。每个容器类型由最多24个字母数字字符组成的字符串组成。下一行包含一个正整数m (1 <= m <= 100),表示要插入的设备数量。接下来的m行每一行都列出了一个设备的名称,后面跟着它使用的插头类型(与它需要的插座类型相同)。设备名称是一个最多24个字母数字组成的字符串

    字符。没有两个设备会有完全相同的名称。插头类型与设备名称之间用空格分隔。下一行包含一个正整数k (1 <= k <= 100),表示可用的适配器的不同种类的数量。接下来的k行描述了各种适配器,给出了适配器提供的插座类型,后面是空格,后面是插头类型。

    输出

    包含单个非负整数的行,它表示不能插入的设备的最小数目。

    代码:

      1 //题目上面说的是一种电脑有一种类型的插头,电脑要充电就必须找对应的插座。除此之外你还可以找一个转换器去把电脑插头类型转换一下
      2 //那就可以定义一个st代表最大流起点,en代表最大流终点。
      3 //
      4 //st起点就要和每一台电脑相连,然后再让电脑和转换器连接(连接要求就是连接器开头要和电脑插头类型一样)
      5 //最后再和插头相连。插头再和终点en相连就可以了。具体看代码吧
      6 //
      7 #include<stdio.h>
      8 #include<string.h>
      9 #include<iostream>
     10 #include<algorithm>
     11 #include<queue>
     12 #include<map>
     13 using namespace std;
     14 const int maxn=1005;
     15 const int INF=0x3f3f3f3f;
     16 int head[maxn],cnt,st,en,dis[maxn],cur[maxn];
     17 map<string,int>r;
     18 struct edge
     19 {
     20     int v,next,c,flow;
     21 } e[maxn];
     22 struct shudui
     23 {
     24     string q;
     25     int qq;
     26 } p[maxn];
     27 void add_edge(int x,int y,int z)
     28 {
     29     e[cnt].v=y;
     30     e[cnt].c=z;
     31     e[cnt].flow=0;
     32     e[cnt].next=head[x];
     33     head[x]=cnt++;
     34 }
     35 bool bfs()
     36 {
     37     memset(dis,0,sizeof(dis));
     38     dis[st]=1;
     39     queue<int>r;
     40     r.push(st);
     41     while(!r.empty())
     42     {
     43         int x=r.front();
     44         r.pop();
     45         for(int i=head[x]; i!=-1; i=e[i].next)
     46         {
     47             int v=e[i].v;
     48             if(!dis[v] && e[i].c>e[i].flow)
     49             {
     50                 dis[v]=dis[x]+1;
     51                 r.push(v);
     52             }
     53         }
     54     }
     55     return dis[en];
     56 }
     57 int dinic(int s,int limit)
     58 {
     59     if(s==en || !limit) return limit;
     60     int ans=0;
     61     for(int &i=cur[s]; i!=-1; i=e[i].next)
     62     {
     63         int v=e[i].v,feed;
     64         if(dis[v]!=dis[s]+1) continue;
     65         feed=dinic(v,min(limit,e[i].c-e[i].flow));
     66         if(feed)
     67         {
     68             e[i].flow+=feed;
     69             e[i^1].flow-=feed;
     70             limit-=feed;
     71             ans+=feed;
     72             if(limit==0) break;
     73         }
     74     }
     75     if(!ans) dis[s]=-1;
     76     return ans;
     77 }
     78 int main()
     79 {
     80     int n,m,k,index=1;
     81     while(~scanf("%d",&n))
     82     {
     83         cnt=0;
     84         memset(head,-1,sizeof(head));
     85         index=1;
     86         string qq,q;
     87         st=0;
     88         en=1;
     89         for(int i=2; i<=n+1; ++i)
     90         {
     91             cin>>q;
     92             r[q]=++index;
     93             add_edge(r[q],en,1);  //插头和终点相连
     94             add_edge(en,r[q],0);
     95         }
     96         scanf("%d",&m);
     97         index=n+2+2*m;
     98         for(int i=n+2; i<=n+1+m; ++i)
     99         {
    100             cin>>q>>q;
    101             p[i-n-1].q=q;
    102             p[i-n-1].qq=i+m;
    103             add_edge(st,i,INF);  //电脑和起点相连
    104             add_edge(i,st,0);
    105             add_edge(i,i+m,1);  //这里也就是对电脑进行拆点了,不拆点的话应该也可以
    106             add_edge(i+m,i,0);
    107             if(r[q]==0) r[q]=++index;
    108             add_edge(i+m,r[q],1);   //找到对应插头进行连接
    109             add_edge(r[q],i+m,0);
    110 
    111         }
    112         scanf("%d",&k);
    113         while(k--)
    114         {
    115             cin>>qq>>q;
    116             add_edge(r[qq],r[q],INF);  //转换器能使用多次,所以要建一个容量为INF的边
    117             add_edge(r[q],r[qq],0);
    118         }
    119         r.clear();
    120         int ans=0;
    121         while(bfs())
    122         {
    123             for(int i=0; i<=index; i++)
    124                 cur[i]=head[i];
    125             ans+=dinic(st,1);  //1可以改成无穷大
    126         }
    127         printf("%d
    ",m-ans);
    128     }
    129 
    130     return 0;
    131 }
  • 相关阅读:
    微信小程序缓存
    微信小程序下拉刷新和上拉加载
    小程序杂乱知识点
    2017-01-11小程序常规增删改查
    2017-01-11小程序form表单提交
    20170105数据库表设计知识点
    20170103需要修改的地方
    关于类protected、private、public的方法
    java基础巩固之java实现文件上传
    Java四个常用正则表达
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11782385.html
Copyright © 2020-2023  润新知