Uva753

题意:给你n个插座,然后接下俩的n行是对插座类型的描述,然后给你m个电器,接下来的m行是对电器的描述,电器的种类和电器的插座类型,然后给出k种转换器,接下来的

k行就是第一个字母表示该转换器可以和那种电器相连,第二个字母表示该转换器可以和那个插座相连,注意一种转换器可以有多个。。。。然后让你求得就是不能插上电源的电器有多少个。。

最大流的问题,0作为原点,每个电器的编号是1-m,转换器的编号是m+1到m+k,插座的编号是m+k+1到m+k+n,n+m+k+1作为汇点,求源点到汇点的最大流,然后m-最大流就是答案

建图部分,一定要建成有向图,而且在建图的过程中方向一定不能搞错。。

源点到每个电器的容量为1,然后能和电器相连的转换器的边容量为inf,直接和插座相连的电器的容量为1;转换器转换器之间的容量为inf,转换器和插座之间的容量inf,然后插座和汇点之间的容量是1

#include<stdio.h>
#include<string.h> 
#include<algorithm>
#include<iostream>
#include<string> 
#include<vector>
#include<queue>
const int inf=89999999;
using namespace std;
const int N=1000;
struct node1
{
   string s1;
}c[N];
struct node2
{
    string s1 ,s2;
}d[N];
struct node3
{
    string s1,s2;
}z[N];
struct node4
{
    int v,u; 
    int next;
    int f;
    int cap;
     
}G[N];  
int a[1000];
int head[1000]; 
int p[1000];
int s,t,F;
int num;
void init()
{
    memset(head,-1,sizeof(head));
    num=0;
} 
void add(int u,int v,int w)
{
    G[num].u=u;
    G[num].v=v;
    G[num].cap=w;
    G[num].f=0;
    G[num].next=head[u];
    head[u]=num++;
    int tt=u;
    u=v;
    v=tt;
    G[num].u=u;
    G[num].v=v;
    G[num].cap=0;
    G[num].f=0;
    G[num].next=head[u];
    head[u]=num++;
}
void EK_()
{
    queue<int>q;
    for(;;)
    {   
        memset(p,-1,sizeof(p));
        memset(a,0,sizeof(a)); 
        a[s]=inf; 
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int k=head[u];k!=-1;k=G[k].next)
            { 
            int v=G[k].v;
            if(!a[v]&&G[k].cap>G[k].f)
            {
            p[v]=k;
            q.push(v);
            a[v]=a[u];
            if(a[v]>G[k].cap-G[k].f)
            a[v]=G[k].cap-G[k].f;
            }
            } 
        }   
        //cout<<a[t]<<endl; 
        if(a[t]==0)
        break;
        for(int k=p[t];k!=-1;k=p[G[k].u])
        {
           G[k].f+=a[t];
           G[k^1].f-=a[t];
          // printf("%d\n",k^1); 
        }
        F+=a[t];
    }
}
void printf__()
{
    printf("%d %d\n",s,t);
    for(int i=0;i<num;i++)
    printf("%d %d %d\n",G[i].u,G[i].v,G[i].cap);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
    init();
    int n,m,k;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    cin>>c[i].s1;
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    cin>>d[i].s1>>d[i].s2;
    scanf("%d",&k);
    for(int i=1;i<=k;i++)
    cin>>z[i].s1>>z[i].s2;
    t=m+n+k+1;
    s=0;
    for(int i=1;i<=m;i++)
    {
        add(s,i,1);
        for(int j=1;j<=k;j++)
        {
            if(d[i].s2==z[j].s1)
            add(i,j+m,inf);
        }
        for(int j=1;j<=n;j++)
        {
            if(d[i].s2==c[j].s1)
            add(i,j+m+k,1);
        }
    } 
    for(int i=1;i<=k;i++)
    {
        for(int j=1;j<=k;j++)
        {
            if(i!=j&&z[i].s2==z[j].s1)
            add(i+m,j+m,inf);
        }
        for(int j=1;j<=n;j++)
        {
            if(z[i].s2==c[j].s1)
            add(i+m,m+k+j,inf);
        }
    }
    for(int i=1;i<=n;i++)
    add(m+k+i,t,1);
//    printf__();
    F=0;
    EK_();
    int ans=m-F;
    printf("%d\n",ans);
    if(T!=0)
    printf("\n");
}
return 0;
}
    
    
    
    

 

posted @ 2015-12-31 08:43  __NaCl  阅读(79)  评论(0编辑  收藏  举报