0
点赞
收藏
分享

微信扫一扫

POJ1087DFS+匈牙利或者DINIC

题意:
     有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;

}







举报

相关推荐

0 条评论