zoukankan      html  css  js  c++  java
  • codevs 1027 姓名与ID

    1027 姓名与ID

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 大师 Master
     
     
    题目描述 Description

    有N个人,各自有一个姓名和ID(别名)。每个人的姓名和ID都没有重复。这些人依次进入一间房间,然后可能会离开。过程中可以得到一些信息,告知在房间里的某个人的ID。你的任务是准确地确定每个人的ID。

    输入描述 Input Description

    第一行是整数N,表示N个人,N<=20。

    接下来的一行是N个人的ID,用一个空格分隔。

    接下来的若干行是过程的记录:一个字母和一个字符串。字母是E、L或M中的一个。E表示进入房间,后面跟的字符串表示进来的人的姓名;L表示离开房间,后面跟的字符串表示离开的人的姓名;M表示回答询问,后面跟的字符串表示:当前用这个ID人在房间里面。

    最后一行Q表示结束。

    所有的姓名和ID都由不超过20个的小写字母组成。所有姓名都会在记录中出现。

    一开始时,房间时空的。

    输出描述 Output Description

    共N行,每行形如:“姓名:ID”,如果ID不能确定,输出???。

    按照姓名的字典顺序输出。

    样例输入 Sample Input

    7

    bigman mangler sinbad fatman bigcheese frenchie capodicapo

    E mugsy

    E knuckles

    M bigman

    M mangler

    L mugsy

    E clyde

    E bonnie

    M bigman

    M fatman

    M frenchie

    L clyde

    M fatman

    E ugati

    M sinbad

    E moriarty

    E booth

    Q

    样例输出 Sample Output

    bonnie:fatman

    booth:???

    clyde:frenchie

    knuckles:bigman

    moriarty:???

    mugsy:mangler

    ugati:sinbad

    数据范围及提示 Data Size & Hint

     

    /*
    什么都没用结果得了90分 
    求错误在那??????
    正解 二分图匹配  在下面 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<map>
    #include<algorithm>
    using namespace std;
    int n,tot,topt,g[50],a[50][50],sum[50];
    string s[50];
    string ss[50];
    map<string,int>p;
    map<string,int>f;
    queue<int>q;
    struct node
    {
        string xingming;
        string ID;
    }fin[50];
    int cmp(node x,node y)
    {
        return x.xingming<y.xingming;
    }
    int main()
    {
        int i,j,k; 
        cin>>n;
        for(i=1;i<=n;i++)
        {
            cin>>s[i];
            sum[i]=n;
            f[s[i]]=i;
        }
        char c;
        while(1)
        {
            cin>>c;
            if(c=='Q')break;
            if(c=='E')
            {
                string st;
                cin>>st;
                if(p[st]==0)
                {
                    ss[++tot]=st;
                    p[st]=tot;
                }
                g[p[st]]=1;
            }
            if(c=='L')
            {
                string st;
                cin>>st;
                g[p[st]]=0;
            }
            if(c=='M')
            {
                string st;
                cin>>st;
                int t=f[st];
                for(i=1;i<=n;i++)
                {
                    if(i>tot||g[i]==0||a[i][t]==1)
                    {
                        if(a[i][t]==0)sum[t]--;
                        a[i][t]=1;
                    }
                }
            }
        }
        for(i=1;i<=n;i++)
        if(sum[i]==1)
        q.push(i);
        while(!q.empty())
        {
            int d=q.front();
            q.pop();
            for(i=1;i<=n;i++)
            if(a[i][d]==0)
            {
                for(j=1;j<=n;j++)
                if(j!=d)
                {
                    if(a[i][j]==0)
                    {
                        sum[j]--;
                        if(sum[j]==1)q.push(j);
                    }
                    a[i][j]=1;
                }
            }
        }
        for(i=1;i<=n;i++)
        {
            fin[i].xingming=ss[i];
            int flag=0;
            for(j=1;j<=n;j++)
            if(a[i][j]==0&&sum[j]==1)
            {
                fin[i].ID=s[j];
                flag=1;
            }
            if(flag==0)fin[i].ID="???";
        }
        sort(fin+1,fin+n+1,cmp);
        for(i=1;i<=n;i++)
        cout<<fin[i].xingming<<":"<<fin[i].ID<<endl;
        return 0;
    }
    /*
    二分图匹配
    刚开始每个人和每个ID都连一条边 刚开始都有可能 
    有一个数组记录是否在房间内 当E和L操作时更新此数组 
    当M时 把此时的ID和不在房间内的人边取消掉
    结束后
    把现在还连着的边取消掉 看看是否能完没匹配
    若不能 则说明这条边应该连 记录这条边两边的姓名与ID 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<map>
    #include<algorithm>
    using namespace std;
    int n,tot,topt,g[50],a[50][50],match[50],ff[50];
    string s[50];
    string ss[50];
    map<string,int>p;
    map<string,int>f;
    queue<int>q;
    struct node
    {
        string xingming;
        string ID;
    }fin[50];
    int cmp(node x,node y)
    {
        return x.xingming<y.xingming;
    }
    int dfs(int x)
    {
        for(int i=1;i<=n;i++)
        {
            if(a[x][i]==0&&!ff[i])
            {
                ff[i]=1;
                if(!match[i]||dfs(match[i]))
                {
                    match[i]=x;
                    return 1;
                }
            }
        }
        return 0;
    }
    int main()
    {
        int i,j,k; 
        cin>>n;
        for(i=1;i<=n;i++)
        {
            cin>>s[i];
            f[s[i]]=i;
        }
        char c;
        while(1)
        {
            cin>>c;
            if(c=='Q')break;
            if(c=='E')
            {
                string st;
                cin>>st;
                if(p[st]==0)
                {
                    ss[++tot]=st;
                    p[st]=tot;
                }
                g[p[st]]=1;
            }
            if(c=='L')
            {
                string st;
                cin>>st;
                g[p[st]]=0;
            }
            if(c=='M')
            {
                string st;
                cin>>st;
                int t=f[st];
                for(i=1;i<=n;i++)
                  if(g[i]==0)
                    a[i][t]=1;
            }
        }
        for(i=1;i<=n;i++)
        {
            int flag=0;
            fin[i].xingming=ss[i];
            for(j=1;j<=n;j++)
            if(a[i][j]==0)
            {
                a[i][j]=1;
                int sum=0;
                memset(match,0,sizeof(match));
                for(k=1;k<=n;k++)
                {
                    memset(ff,0,sizeof(ff));
                    if(dfs(k))
                    sum++;
                }
                if(sum<n)
                {
                    fin[i].ID=s[j];
                    flag=1;
                    a[i][j]=0;
                    break;
                }
                a[i][j]=0;
            }
            if(!flag)fin[i].ID="???";
        }
        sort(fin+1,fin+n+1,cmp);
        for(i=1;i<=n;i++)
        cout<<fin[i].xingming<<":"<<fin[i].ID<<endl;
        return 0;
    }
  • 相关阅读:
    SDK manager打不开解决办法(转载)
    debian安装中文字体
    rtos之定时器实现
    rtos学习之支持多优先级
    RT-Thread 的空闲线程和阻塞延时
    RT-Thread之对象容器
    RT-Thread 之临界段保护
    RT-Thread之线程实现就绪列表
    rtos 学习之链表
    RTOS 的学习之创建线程
  • 原文地址:https://www.cnblogs.com/dingmenghao/p/5760334.html
Copyright © 2011-2022 走看看