题意:

     有n个插孔,m个电器,q种转换器(转换器可以无限用),然后问你最多有多少个电器能充电。

思路:

      比较简单,就是在建图的时候要考虑下,我用了两种方法做的,一个是最大流,这个方法我的建图是这样,先给每个用电器虚拟出来一个点n,每个插座虚拟出来两个点(限流)m,然后给每个插座或者是插头的类型虚拟出来一个点,这样就ok了,建图是这样

s         -> 所有用电器       1

所有用电器->他所连接的种类    1

种类      ->种类             INF   这个是转换器

种类      ->插座              1

插座到    ->插座              1    限流

插座      -> t                1

然后一遍s到t的最大流

另一种方法是用二分匹配,这个方法我们可以这样想,建立二分图,左边是用电器,右边是插座,然后用电器和插座能连的条件是可以直接或者间接连接上,这个地方可以用搜索搞定,这样在处理所有连接关系的时候的时间复杂度一共是n^2的,一开始想用Floyd了,考虑到那样的话最坏的情况会达到500*500*500就没用,通过搜索建立间接之后就可以直接匈牙利匹配了,下面是两种方法的代码。

DINIC

#include<map>

#include<queue>

#include<stdio.h>

#include<string>

#include<string.h>

#define N_node 700 + 10

#define N_edge 700 * 700 + 50

#define INF 1000000000

using namespace std;

typedef struct

{

    int to ,cost ,next;

}STAR;

typedef struct

{

    int x ,t;

}DEP;

STAR E[N_edge];

DEP xin ,tou;

map<string ,int>mark;

int deep[N_node];

int list[N_node] ,listt[N_node] ,tot;

void add(int a ,int b ,int c)

{

    E[++tot].to = b;

    E[tot].cost = c;

    E[tot].next = list[a];

    list[a] = tot;

    E[++tot].to = a;

    E[tot].cost = 0;

    E[tot].next = list[b];

    list[b] = tot;

}

int minn(int x ,int y)

{

    return x < y ? x : y;

}

bool BFS_DEEP(int s ,int t ,int n)

{

    memset(deep ,255 ,sizeof(deep));

    xin.x = s ,xin.t = 0;

    queue<DEP>q;

    q.push(xin);

    deep[s] = 0;

    while(!q.empty())

    {

        tou = q.front();

        q.pop();

        for(int k = list[tou.x] ;k ;k = E[k].next)

        {

            xin.x = E[k].to;

            xin.t = tou.t + 1;

            if(deep[xin.x] != -1 || !E[k].cost)

            continue;

            deep[xin.x] = xin.t;

            q.push(xin);

        }

    }

    for(int i = 0 ;i <= n ;i ++)

    listt[i] = list[i];

    return deep[t] != -1;

}

int DFS_Flow(int s ,int t ,int flow)

{

    if(s == t) return flow;

    int nowflow = 0;

    for(int k = listt[s] ;k ;k = E[k].next)

    {

        listt[s] = k;

        int to = E[k].to ,c = E[k].cost;

        if(!c || deep[to] != deep[s] + 1)

        continue;

        int tmp = DFS_Flow(to ,t ,minn(c ,flow - nowflow));

        nowflow += tmp;

        E[k].cost -= tmp;

        E[k^1].cost += tmp;

        if(flow == nowflow)

        break;

    }

    if(!nowflow) deep[s] = 0;

    return nowflow;

}

int DINIC(int s ,int t ,int n)

{

    int ans = 0;

    while(BFS_DEEP(s ,t ,n))

    {

        ans += DFS_Flow(s ,t ,INF);

    }

    return ans;

}

int main ()

{

    int n ,m ,q ,i;

    char str1[25+5] ,str2[25+5];

    while(~scanf("%d" ,&n))

    {

        memset(list ,0 ,sizeof(list));

        tot = 1;

        mark.clear();

        int nowid = 0;

        int s = 0 ,t = 705;

        for(i = 1 ;i <= n ;i ++)

        {

            scanf("%s" ,str1);

            if(!mark[str1]) mark[str1] = ++nowid;

            add(mark[str1] + 200 ,mark[str1] + 600 ,1);

            add(mark[str1] + 600 ,i + 100 ,1);

            add(i + 100 ,t ,1);

        }

        scanf("%d" ,&m);

        for(i = 1 ;i <= m ;i ++)

        {

            scanf("%s %s" ,str1 ,str2);

            if(!mark[str2]) mark[str2] = ++nowid;

            add(s ,i ,1);

            add(i ,mark[str2] + 200 ,1);

        }

        scanf("%d" ,&q);

        for(i = 1 ;i <= q ;i ++)

        {

            scanf("%s %s" ,str1 ,str2);

            if(!mark[str1]) mark[str1] = ++nowid;

            if(!mark[str2]) mark[str2] = ++nowid;

            add(mark[str1] + 200 ,mark[str2] + 200 ,INF);

        }

        printf("%d\n" ,m - DINIC(s ,t ,705));

    }

    return 0;

}

匈牙利+DFS

#include<map>

#include<stdio.h>

#include<string>

#include<string.h>

#define N_node 500

#define N_edge 500 * 500 + 10

#define INF 100000000

using namespace std;

typedef struct

{

    int to ,next;

}STAR;

STAR E[N_edge];

int mkdfs[N_node] ,mkgx[N_node];

int list[N_node] ,tot;

int _map[N_node][N_node];

int cz[N_node] ,dq[N_node];

map<string ,int>mark;

void add(int a ,int b)

{

    E[++tot].to = b;

    E[tot].next = list[a];

    list[a] = tot;

}

void DFS(int s ,int now)

{

    for(int k = list[now] ;k ;k = E[k].next)

    {

        int to = E[k].to;

        if(mkdfs[to]) continue;

        mkdfs[to] = _map[s][to] = 1;

        DFS(s ,to);

    }

    return ;

}

int DFS_XYL(int x)

{

    for(int k = list[x] ;k ;k = E[k].next)

    {

        int to = E[k].to;

        if(mkdfs[to]) continue;

        mkdfs[to] = 1;

        if(mkgx[to] == -1 || DFS_XYL(mkgx[to]))

        {

            mkgx[to] = x;

            return 1;

        }

    }

    return 0;

}

int main ()

{

    int n ,m ,q ,i ,j ,a ,b;

    char str1[30] ,str2[30];

    while(~scanf("%d" ,&n))

    {

        mark.clear();

        int nowid = 0;

        for(i = 1 ;i <= n ;i ++)

        {

            scanf("%s" ,str1);

            if(!mark[str1]) mark[str1] = ++nowid;

            cz[i] = mark[str1];

        }

        scanf("%d" ,&m);

        for(i = 1 ;i <= m ;i ++)

        {

            scanf("%s %s" ,str1 ,str2);

            if(!mark[str2]) mark[str2] = ++nowid;

            dq[i] = mark[str2];

        }

        memset(list ,0 ,sizeof(list));

        tot = 1;

        scanf("%d" ,&q);

        for(i = 1 ;i <= q ;i ++)

        {

            scanf("%s %s" ,str1 ,str2);

            if(!mark[str1]) mark[str1] = ++nowid;

            if(!mark[str2]) mark[str2] = ++nowid;

            add(mark[str1] ,mark[str2]);

        }

        memset(_map ,0 ,sizeof(_map));

        for(i = 1 ;i <= nowid ;i ++)

        {

            memset(mkdfs ,0 ,sizeof(mkdfs));

            _map[i][i] = 1;

            DFS(i ,i);

        }

        memset(list ,0 ,sizeof(list));

        tot = 1;

        for(i = 1 ;i <= m ;i ++)

        for(j = 1 ;j <= n ;j ++)

        if(_map[dq[i]][cz[j]]) add(i ,j);

        int ans = 0;

        memset(mkgx ,255 ,sizeof(mkgx));

        for(i = 1 ;i <= nowid ;i ++)

        {

            memset(mkdfs ,0 ,sizeof(mkdfs));

            ans += DFS_XYL(i);

        }

        printf("%d\n" ,m - ans);

    }

    return 0;

}

POJ1087DFS+匈牙利或者DINIC的更多相关文章

  1. 二分图最大匹配模板【匈牙利;Dinic最大流】

    二分图最大匹配模板[匈牙利:Dinic最大流] 匈牙利算法 int n,m; vector<int> map[100010]; int match[100010];//保存匹配的互相点 b ...

  2. 【题解】Uoj79一般图最大匹配

    带花树裸题,感觉带花树强强……不会的勿看此文,解释的可能不对,只是给自己看的!!!如题,带花树即为求一般图最大匹配算法(匈牙利与dinic为二分图最大匹配).推荐论文:2015年<浅谈图的匹配算 ...

  3. 【二分】【字符串哈希】【二分图最大匹配】【最大流】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem I. Minimum Prefix

    给你n个字符串,问你最小的长度的前缀,使得每个字符串任意循环滑动之后,这些前缀都两两不同. 二分答案mid之后,将每个字符串长度为mid的循环子串都哈希出来,相当于对每个字符串,找一个与其他字符串所选 ...

  4. 【bzoj2044】三维导弹拦截 dp+二分图最大匹配

    题目描述 n个物品,第i个位置有ai.bi.ci三种属性.每次可以选出满足$\ a_{p_i}<a_{p_{i+1}}\ ,\ b_{p_i}<b_{p_{i+1}}\ ,\ c_{p_i ...

  5. [bzoj2150]部落战争_二分图最小路径覆盖

    部落战争 bzoj-2150 题目大意:题目链接. 注释:略. 想法: 显然是最小路径覆盖,我们知道:二分图最小路径覆盖等于节点总数-最大匹配. 所以我们用匈牙利或者dinic跑出最大匹配,然后用总结 ...

  6. 网络流基础&网络流24题

    网络最大流 dinic+当前弧优化. const int N=10007,M=100007,inf=1e9; int s,t,head[N],ver[M],edge[M],Next[M],tot=1, ...

  7. SDOI2018凉凉记

    好久没有更博客了...因为我在颓废学习.. SDOI一轮结束了...我也该回来学地生了... 凉凉 ————————————————我是分割线———————————————— Day0 愉快感冒的Da ...

  8. luogu3386 【模板】二分图匹配 匈牙利算法 hdu2063 过山车 dinic

    luogu 匈牙利算法 #include <iostream> #include <cstring> #include <cstdio> using namespa ...

  9. Bzoj 2718: [Violet 4]毕业旅行 && Bzoj 1143: [CTSC2008]祭祀river 传递闭包,二分图匹配,匈牙利,bitset

    1143: [CTSC2008]祭祀river Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1878  Solved: 937[Submit][St ...

随机推荐

  1. c++:一个辅助类让内存泄漏现原形!

    前言 对于c++而言,如何查找内存泄漏是程序员亘古不变的话题:解决之道可谓花样繁多.因为最近要用到QT写程序,摆在我面前的第一个重要问题是内存防泄漏.如果能找到一个简单而行之有效的方法,对后续开发大有 ...

  2. Ubuntu 18.04下Intel SGX应用程序程序开发——获得OCALL调用的返回值

    本文中,我们介绍在Enclave函数中调用不可信OCALL函数,并获得OCALL函数的返回值. 1. 复制SampleEnclave示例并建立自己的OcallRetSum项目 SampleEnclav ...

  3. 最新版Swagger 3升级指南和新功能体验!

    Swagger 3.0 发布已经有一段时间了,它于 2020.7 月 发布,但目前市面上使用的主流版本还是 Swagger 2.X 版本和少量的 1.X 版本,然而作为一名合格的程序员怎么能不折腾新技 ...

  4. 前端性能监控之performance

    如果我们想要对一个网页进行性能监控,那么使用window.performance是一个比较好的选择. 我们通过window.performance可以获取到用户访问一个页面的每个阶段的精确时间,从而对 ...

  5. Spring(一):Spring概述及相关概念

    Spring简介 Spring主要作用是用来解耦,降低代码之间的耦合度.根据功能的不同,可以将系统的代码分为主业务逻辑与系统服务逻辑. 主业务逻辑之间代码联系紧密,相互调用较多,复用性相对较低: 系统 ...

  6. python-6-1

    1.定义一个时间戳转换成格式化时间的函数import time def timestamp_to_fomat(timestamp= None,format ='%Y-%m-%d %H:%M:%S' ) ...

  7. python-3-2

    一 切片 1.切片是list取值的一种方式 列子: nums = ['a','b','c','d','e','f','h','g','k','l','kk','nn','ee'] 取b和c元素出来 p ...

  8. java例题_10小球 自由落体

    1 /*10 [程序 10 自由落体] 2 题目:一球从 100 米高度自由落下,每次落地后反跳回原高度的一半: 3 求它在 第 10 次落地时,共经过多少米? 4 第 10 次反弹多高? 5 */ ...

  9. 移动端调试vConsole

    当我们在进行移动端开发的时候,经常会出现在pc显示正常,在移动端却各种异常的情况.这时候我们在手机上又看不到error log. 所以我们就需要vConsole这样一个移动端开发神器. 那具体要怎么使 ...

  10. 热更新基础--AssetBundle学习笔记

    一.简介 AssetBundle简称AB包,特定平台的资产压缩包(包括模型.贴图.预设体.音效.材质球等资产). 作用:Resources下的资源只读且打包后不可修改,而AB包存储位置自定,后期可以动 ...