题目链接
http://www.sdutacm.org/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2083/pid/3805.html
离散题目11
Time Limit: 1000MS Memory Limit: 65536KB
Submit Statistic
Problem Description

给定一个数学函数写一个程序来确定该函数是否是双射(既是单射,又是满射)的。

如果每个可能的像至少有一个变量映射其上(即像集合B中的每个元素在A中都有一个或一个以上的原像),或者说值域任何元素都有至少有一个变量与之对应,那这个映射就叫做满射。

单射
即A中的任意一个元素唯一的对应一个函数值,并且该值为B集合中的某个元素。
Input

多组输入。 第一行输入三个整数n,m,k,分别表示集合a中的元素个数,集合b中的元素个数,集合a到b的映射个数。 第二行输入n个数,代表集合a中的元素。 第三行输入m个数,代表集合b中的元素。接下来k行,每行两个数,代表集合a中的元素x和x在集合b中的像y。
Output

每组数据输出一行,若F为a到b的双射,输出”YES”, 否则输出”NO”。
Example Input

5 5 5
1 2 3 7 8
2 5 6 9 0
1 9
3 2
2 6
7 0
8 5
Example Output

YES
Hint

保证集合a中元素无重复,集合b中元素无重复,映射关系无重复(如:{,})
1<=n,m,k<=1000
1<=a[i], b[i]<=10000
x∈a, y∈b
Author

Stone

#include<bits/stdc++.h>
#include<iostream>
using namespace std;

int main()
{
    int n,m;
    while(cin>>n)
    {
        int k;
        cin>>m>>k;
        int u = 0;
        int book[100005]={0};
        int b[100005]={0};
        for(int i=1;i<=n;i++)
        {
            int num;
            cin>>num;
        }
        for(int i=1;i<=m;i++)
        {
            int num;
            cin>>num;
            b[num]++;
        }
        int f = 0;

        for(int i=1;i<=k;i++)
        {
            int x,y;
            cin>>x>>y;

            if(b[y]==1)//判断满射条件,记录y在映射中的个数(只记录条件中的,重复的只记一次),因为无重复,所以只需个数等于m即可
            {
                b[y]++;
                u++;
            }
            if(f)
                continue;
            if(book[x]==1)//判断单设条件,映射中x只能出现一次,且映射的y在条件中必须存在
            {
                f = 1;
            }
            if(b[y]==0)
            {
                f = 1;
            }
                book[x] = 1;
        }

        if(u>=m&&!f)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}