首页 > 其他分享 >POJ1904 King's Quest

POJ1904 King's Quest

时间:2023-07-28 10:12:55浏览次数:47  
标签:King 每个 POJ1904 Quest 王子 ans 妹子 include 分量

\(POJ1904\) \(King's\) \(Quest\)

一、题目描述

有\(n\)个王子,每个王子都有\(k\)个喜欢的妹子,每个王子只能和喜欢的妹子结婚。现有一个匹配表,将每个王子都与一个自己喜欢的妹子配对。请你根据这个表得出每个王子可以和几个自己喜欢的妹子结婚,按序号升序输出妹子的编号,这个表应满足所有的王子最终都有妹子和他结婚(一个妹子只能嫁给一个王子)。

二、题目解析

看到题目时,一脸懵逼,只觉得题面很有(ci)趣(ji)

但没办法啊,为了王国的一夫一妻制我们只好努力啊awa

让我们首先来考虑建图

  • 如果王子\(u\)喜欢妹子\(v\)那我们可以从\(u\)向\(v\)连一条有向边

  • 如果妹子\(v\)可以与王子\(u\)配对(即在配对表上),那我们可以从\(v\)向\(u\)连一条有向边

对于样例

4
2 1 2
2 1 2
2 2 3
2 3 4
1 2 3 4

我们建出了这样一张图:

红的是王子,蓝的是妹子,绿的表示从王子到公主,黄的表示从妹子到王子

仔细观察我们发现了这张图的一些特别之处:

每个紫色框出的部分都是个 强连通分量

这意味着什么?

这说明 这个分量内的每个王子和这个分量内的每个妹子都可以随意匹配

答案只需要枚举王子和他所在分量内的妹子即可

而这个强连通分量又该咋求呢?

当然就是\(tarjan\)啦

  • \(UVA\)的题目是有多组数据的,\(POJ\)的每个点只有一组数据,下面的的代码以多组数据为例,但\(POJ\)上也能过
  • 代码中王子编号\(1..n\),妹子编号\(n+1..2n\)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cstdio>
#include <vector>
using namespace std;
const int N = 4010, M = N * N; // 这个M太BT了!黄海就WA到这里!我一直尝试 M= N<<1, M = N<<2,结果一直错错错!

int n, m; // n个王子,n个姑娘,每个王子喜欢m个姑娘

// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}

// tarjan算法求强连通分量
int stk[N], top;    // tarjan算法需要用到的堆栈
bool in_stk[N];     // 是否在栈内
int dfn[N];         // dfs遍历到u的时间
int low[N];         // 从u开始走所能遍历到的最小时间戳
int ts;             // 时间戳,dfs序的标识,记录谁先谁后
int id[N], scc_cnt; // 强连通分量块的最新索引号
int sz[N];          // sz[i]表示编号为i的强连通分量中原来点的个数
void tarjan(int u) {
    dfn[u] = low[u] = ++ts;
    stk[++top] = u;
    in_stk[u] = 1;
    for (int i = h[u]; ~i; i = ne[i]) {
        int j = e[i];
        if (!dfn[j]) {
            tarjan(j);
            low[u] = min(low[u], low[j]);
        } else if (in_stk[j])
            low[u] = min(low[u], dfn[j]);
    }

    if (dfn[u] == low[u]) {
        ++scc_cnt; // 强连通分量的序号
        int x;     // 临时变量x,用于枚举栈中当前强连通分量中每个节点
        do {
            x = stk[top--];    // 弹出节点
            in_stk[x] = false; // 标识不在栈中了
            id[x] = scc_cnt;   // 记录每个节点在哪个强连通分量中
            sz[scc_cnt]++;     // 这个强连通分量中节点的个数+1
        } while (x != u);
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("POJ1904.in", "r", stdin);
#endif

    while (~scanf("%d", &n)) {   // n个王子,n个姑娘
        memset(h, -1, sizeof h); // 初始化链式前向星
        memset(dfn, 0, sizeof dfn);
        memset(low, 0, sizeof low);
        memset(id, 0, sizeof id);
        memset(in_stk, 0, sizeof in_stk);
        memset(stk, 0, sizeof stk);
        memset(sz, 0, sizeof sz);
        idx = top = scc_cnt = ts = 0;

        for (int i = 1; i <= n; i++) {
            scanf("%d", &m);               // i号王子喜欢几个姑娘
            for (int j = 1; j <= m; j++) { // 是哪几位姑娘
                int x;
                scanf("%d", &x);
                add(i, x + n); // 从王子向妹子连边,建图技巧:(1,n),(n+1,2n)
            }
        }
        for (int i = 1; i <= n; i++) {
            int x;
            scanf("%d", &x);
            add(x + n, i); // 从妹子向王子连边
        }

        // 注意:图中的点是2*n了,每个王子、姑娘都要占一个点
        for (int i = 1; i <= 2 * n; i++)
            if (!dfn[i]) tarjan(i); // 跑tarjan

        for (int u = 1; u <= n; u++) { // 枚举王子
            vector<int> ans;
            for (int i = h[u]; ~i; i = ne[i]) { // 枚举王子喜欢的妹子
                int v = e[i];
                if (id[u] == id[v]) ans.push_back(v - n); // 判断王子和妹子是否在同一强连通分量中
            }
            printf("%d ", ans.size());                                  // 这里一定要注意使用%d,黄海写成%lld一直WA到哭
            sort(ans.begin(), ans.end());                               // 要求按妹子编号升序输出
            for (int i = 0; i < ans.size(); i++) printf("%d ", ans[i]); // 每个王子的可匹配妹子数
            puts("");
        }
    }

    return 0;
}

标签:King,每个,POJ1904,Quest,王子,ans,妹子,include,分量
From: https://www.cnblogs.com/littlehb/p/17586822.html

相关文章

  • oral speaking sentences
    基本表达:Igetuptodolotsofthings.我干很多事情(问:周末你做什么)Iampassionateaboutdoingsth(喜欢做什么)Iamjustanamateur.IplayforfunIamnewtoit   放在前面的条件IfigetachangeIwillpaintwhenIgetachance,Iwillpaint......
  • 配置文件的介绍,静态文件的配置,request对象请求方法,pycharm连接数据库,Django连接My
    配置文件的介绍#注册应用的INSTALLED_APPS=['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.c......
  • 爬虫基本工具:urllib丶requests丶selenium丶pytesseract
    urllib来实现cookie和ip代理1fromurllib.requestimportRequest,build_opener,urlopen2fromfake_useragentimportUserAgent3fromurllib.parseimporturlencode4fromurllib.requestimportHTTPCookieProcessor5fromhttp.cookiejarimportCookieJ......
  • 微信小程序request请求
    request.js //新建http文件夹的request.js//constbaseUrl=require("../utils/env1").dev;//测试环境constbaseURL="https://v.api.aa1.cn/api/pyq";//公用总路径地址//专属域名//暴露出去一个函数,并且接收一个外部传入的参数exportconstrequest=(params)......
  • BlockingQueue介绍
    我们平时开发中好像很少使用到BlockingQueue(阻塞队列),比如我们想要存储一组数据的时候会使用ArrayList,想要存储键值对数据会使用HashMap,在什么场景下需要用到BlockingQueue呢?1.BlockingQueue的应用场景当我们处理完一批数据之后,需要把这批数据发给下游方法接着处理,但是下游方法......
  • python的request.data.get()
    Python中的request.data.get()实现步骤在Python中,我们可以使用request.data.get()来获取请求的数据。它是一种用于获取POST请求数据的方法。下面是实现request.data.get()的步骤:步骤描述1导入必要的库2创建一个POST请求3获取请求数据现在让我们一步一步地......
  • APP - Appium-Inspector连接报错Failed to create session, The requested resource c
    APP-Appium-Inspector连接报错Failedtocreatesession,Therequestedresourcecouldnotbefoundappium版本:Appium-Server-GUI-windows-1.22.3-4Appium-Inspector版本:Appium-Inspector-windows-2022.5.4填写好参数连接时报错: 错误信息:错误Failedtocreatesess......
  • python + requests + unittest 接口自动化进阶篇一
    前言关于接口headers中的Content-Type:Get请求的headers中没有Content-Type这个字段,Post的Content-Type有:application/x-www-form-urlencoded一般是文本表单用post传递数据;multipart/form-data用于文件上传,此时form的enctype属性必须指定为multipart/form-d......
  • Oracle数据类型与对应的PostgreSQL数据类型(oracle 19c 迁移到kingbase)
    Oracle数据类型与对应的PostgreSQL数据类型的映射:1.数值类型:-OracleNUMBER->PostgreSQLNUMERIC-OracleINTEGER->PostgreSQLINTEGER-OracleBINARY_FLOAT->PostgreSQLREAL-OracleBINARY_DOUBLE->PostgreSQLDOUBLEPRECISION2.字符串类型:-Or......
  • 【大联盟】20230714 T1 三分网络(tri) 题解 CF1666K 【Kingdom Partition】
    题目描述here。题解赛时得分:\(30/30\),想了很久网络流最后不会。感觉这题就纯纯对脑洞,因为把题目中的\(2\)改成\(3\)就做不了)))不过还是相当有意思的。考虑如下建模方式:首先,考虑最小割。对于每个点\(i\),我们用两个点\(x_{i}\),\(y_i\)来表示。\(x_i\)表示\(i\)号点是......