1327B Princesses and Princes(模拟)

1327B Princesses and Princes(模拟)

题面

题意:有 TT​ 组询问,每组询问第一行一个整数 nn​ 表示有 nn​ 个公主以及 nn​ 个王子需要进行联姻,按顺序给出第 1n1\sim n​ 个公主的心仪王子列表,默认每个公主都会选择跟列表中没有被之前公主选择的王子进行联姻。国王希望联姻成功的公主与王子对数越多越好,现在允许劝说其中某个公主与某个没有被任何公主喜欢的王子进行联姻,如果这样做之后联姻成功的对数增加,则输出 “IMPROVE”,再输出被劝说的公主 ii​ 以及联姻的王子 jj​,否则输出 “OPTIMAL”。

范围1T105 , 1n1051 \le T \le 10^5~,~1 \le n \le 10^5​

分析:因为每个公主的选择方式都已经确定了,我们只需要进行模拟就可以计算出当前情况下的最大匹配数,如果最大匹配数 <n< n​ 则可以劝说任意一个没有匹配的公主以及一个没有被任何公主喜欢的王子进行联姻,使答案增加,否则说明已经所有公主都匹配上了,劝说也没有用了,不会出现更多的虚空公主。

Notice​:不要用 memsetmemset,会 TLETLE,主要初始化 1n1\sim n​ 范围内的数组元素就可以了。

Code

#include <bits/stdc++.h>
#define int long long
#define double long double
using namespace std;

const int MAXN = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const double PI = acos(-1.0);

int n;

inline int read()
{
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
        s = s * 10 + ch - '0', ch = getchar();
    return s * w;
}

// vis[i]保存王子i是否被喜欢,vis2[i]表示公主i是否匹配上
int vis[MAXN], vis2[MAXN];

signed main()
{
    int T = read();
    while (T--)
    {
        n = read();
        // 不要用memset!1e5的T,每次初始化1e5的数组,肯定T!
        for (int i = 1; i <= n; i++)
        {
            vis[i] = vis2[i] = 0;
        }
        int cnt = 0;
        for (int i = 1; i <= n; i++)
        {
            int k = read();
            // 保存公主i是否匹配上了
            int update = 0; 
            for (int j = 0; j < k; j++)
            {
                int x = read();
                // 王子x没被选择并且公主i没有匹配上
                if (!vis[x] && !update)
                {
                    // 王子x和公主i进行联姻
                    vis[x] = 1;
                    vis2[i] = 1;
                    cnt++;
                    update = 1;
                }
            }
        }
        // 已经达到最优解,没法改进
        if (cnt == n)
        {
            cout << "OPTIMAL" << endl;
        }
        // 否则输出任意一队满足条件的公主与王子即可
        else
        {
            cout << "IMPROVE" << endl;
            for (int i = 1; i <= n; i++)
            {
                if (!vis2[i])
                {
                    cout << i << " ";
                    break;
                }
            }
            for (int i = 1; i <= n; i++)
            {
                if (!vis[i])
                {
                    cout << i << endl;
                    break;
                }
            }
        }
    }
    return 0;
}

【END】感谢观看

发布了61 篇原创文章 · 获赞 27 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览