poj1087(最大流)

来源:互联网 发布:中国乒乓球 知乎 编辑:程序博客网 时间:2024/06/07 04:47

链接:点击打开链接

题意:在一个会议室里有n种插座,每种插座一个,每个插座只能插一种以及一个电器(或者适配器),有m个电器,每个电器有一个插头需要插在相应一种插座上,有k种适配器,每种适配器可以有无限多数量,每种适配器(a, b)可以把b类插座变为a类插座,问最后有多少个电器无法使用

代码:

#include <set>#include <queue>#include <vector>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>using namespace std;const int INF=0x3f3f3f3f;struct node{    int u,v,cap;    node(){}    node(int u,int v,int cap):u(u),v(v),cap(cap){}}es[505*505];int R,S,T,K;int dis[505],iter[505];char name[505][50];vector<int> tab[505];void addedge(int u, int v, int cap){    tab[u].push_back(R);    es[R++]=node(u,v,cap);    tab[v].push_back(R);    es[R++]=node(v,u,0);}int bfs(){    int i,h;    queue<int> q;    q.push(S);    memset(dis,INF,sizeof(dis));    dis[S]=0;    while(q.size()){        h=q.front();        q.pop();        for(i=0;i<tab[h].size();i++){            node &e=es[tab[h][i]];            if(e.cap>0&&dis[e.v]==INF){                dis[e.v]=dis[h]+1;                q.push(e.v);            }        }    }    return dis[T]<INF;}int dfs(int x,int maxflow){    int flow;    if(x==T)    return maxflow;    for(int &i=iter[x];i<tab[x].size();i++){        node &e=es[tab[x][i]];        if(dis[e.v]==dis[x]+1&&e.cap>0){            flow=dfs(e.v,min(maxflow,e.cap));            if(flow){                e.cap-=flow;                es[tab[x][i]^1].cap+=flow;                return flow;            }        }    }    return 0;}int judge(char str[]){    int i;    if(K==0){        strcpy(name[1],str);        K=1;        return 1;    }    for(i=1;i<=K;i++)    if(strcmp(name[i],str)==0)    return i;                                   //判断是否出现过    K++;    strcpy(name[K],str);    return K;}                                               //直接返回当前串的编号int dinic(){    int ans,flow;    ans=0;    while(bfs()){        memset(iter,0,sizeof(iter));        while(flow=dfs(S,INF))        ans+=flow;    }    return ans;}                                               //网络流模板int main(){    int n,i,j,tmp;    char s[50],str[50];    while(scanf("%d",&n)!=EOF){        R=S=K=0,T=500;                          //不知道节点个数时可以将汇点设的大一点        memset(name,0,sizeof(name));        for(i=0;i<=T;i++)        tab[i].clear();        scanf("%d",&n);        for(i=0;i<n;i++){            scanf("%s",s);            addedge(S,judge(s),1);              //插头与源点相连        }        scanf("%d",&n);        for(i=0;i<n;i++){            scanf("%s%s",s,str);            addedge(judge(s),T,1);              //用电器与汇点相连            addedge(judge(str),judge(s),1);     //插座和用电器相连        }        tmp=n;        scanf("%d",&n);        for(i=0;i<n;i++){            scanf("%s%s",s,str);            addedge(judge(str),judge(s),INF);   //可以转换的换位容量是INF的边        }        printf("%d\n",tmp-dinic());    }    return 0;}


 

0 0
原创粉丝点击