2016 ICPC合肥站 传递 HDU-5961(拓扑排序 / bitset / 暴力(可hack))

news2024/7/30 5:41:02

题目链接:HDU-5961 传递
中文题面就不解释题目意思,解释一下名词的意思
完全图:对于一个无向图 G G G 而言,设点集为 V V V,点集中任意不相同两点 u , v u, v u,v 间都有且仅有一条边叫做完全图。
竞赛图:在一个完全图的基础上给所有边定向,就变成了竞赛图。
可传递:在一个有向图中若存在边 ( a → b ) (a\rightarrow b) (ab)(代表一条由 a a a 指向 b b b 的边,下同),和 ( b → c ) (b\rightarrow c) (bc)。则一定要存在边 ( a → c ) (a\rightarrow c) (ac) 若不存在即不合法。

拓扑排序

思路

我认为的正解,很妙的反向建图的思路,一直思考暴力没往这方面想。

考虑任意图不合法的情况

  1. 有环存在同一图中: ( a → b ) ( b → c ) ( c → a ) (a\rightarrow b) (b\rightarrow c) (c\rightarrow a) (ab)(bc)(ca)
    在这里插入图片描述

  2. 存在需要满足可传递的前置情况,却少了边
    P P P 图: ( a → b ) ( b → c ) (a\rightarrow b) (b\rightarrow c) (ab)(bc) (理应要有 ( a → c ) (a\rightarrow c) (ac) 才合法,但这条边却存在与另一图中)
    Q Q Q 图: ( a → c ) / ( c → a ) (a\rightarrow c) / (c\rightarrow a) (ac)/(ca)
    在这里插入图片描述
    在这里插入图片描述

情况1:只需要对图跑一遍拓扑排序判环即可解决。
情况2:因为竞赛图是在完全图基础上定向而来,那么如果一个图P仅有 ( a → b ) ( b → c ) (a\rightarrow b) (b\rightarrow c) (ab)(bc),没有 ( a → c ) / ( c → a ) (a\rightarrow c) / (c\rightarrow a) (ac)/(ca)
不是情况1的环但也不合法, 但 ( a → c ) / ( c → a ) (a\rightarrow c) / (c\rightarrow a) (ac)/(ca) 一定会存在另一张图 Q Q Q 中。
如果 Q Q Q 图中存在的是 ( c → a ) (c \rightarrow a) (ca),那么我们如果将两个图合并起来,就会形成 ( a → b ) ( b → c ) ( c → a ) (a\rightarrow b) (b\rightarrow c) (c\rightarrow a) (ab)(bc)(ca) 的环。
如果存在的是 ( a → c ) (a \rightarrow c) (ac),那么我们将 Q Q Q 图的边反向再与图 P P P 合并那么也将构成环。

于是得出结论:将 P , Q P,Q PQ 图中任意一个反向记为 Q ′ Q' Q(不妨假设将 Q Q Q 反向)
将图 P , Q P, Q P,Q 合并拓扑排序判环,再将图 P , Q ′ P,Q' P,Q 合并拓扑排序判环 任意情况有环即不合法。

网上很多题解都仅仅是将图 Q Q Q 反向与 P P P 合并判环,而没有将原图 Q Q Q P P P 反向判环这是错误的,两者都需要才能正确判断,这里提供一个hack样例。

input:
2
3
-P-
--P
Q--
3
-PQ
--P
---

output:
N
N

代码:

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

const int N = 2023;
char mp[N][N];

int n, head[N], in[N], tot;
struct edge{
    int to, nex;
}e[N * N];

void add(int from, int to){
    in[to] ++;
    e[++ tot].to = to;
    e[tot].nex = head[from];
    head[from] = tot;
}

void build(int op){ // 建图
    tot = 0;
    for(int i = 1; i <= n; i ++) {
        in[i] = head[i] = 0;
    }
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= n; j ++){
            if(mp[i][j] == 'P') add(i, j);
            if(mp[i][j] == 'Q'){ 
                if(op == 1) add(i, j); // 正
                else add(j, i); // 反
            }
        }
    }
}

queue<int>q;
bool topsort(int op){
    build(op);
    vector<int>cnt;
    
    for(int i = 1; i <= n; i ++){
        if(!in[i]) q.push(i);
    }

    while(!q.empty()){
        int u = q.front(); q.pop();
        cnt.push_back(u);
        for(int i = head[u]; i; i = e[i].nex){
            int v = e[i].to; in[v] --;
            if(!in[v]) q.push(v);
        }
    }
    return (int)cnt.size() == n;
}

void solve(){
    scanf("%d",&n);
    for(int i = 1; i <= n; i ++){
        scanf("%s", mp[i] + 1);
    }
    
    if(!topsort(1) || !topsort(0)) puts("N");
    else puts("T");
}

int main(){
    int t;
    scanf("%d",&t);
    while(t --){
        solve();
    }
    return 0;
}

暴力

思路

将图用邻接表存(vector / 链式前向星)对两个图分别三重for循环暴力判断。注意这种方法是可以被hack掉的,但是不知道是赛时数据弱还是怎么回事,能成功AC。
接下来给出hack样例和构造方法:其实就是让所有边都只存在一张图 P P P 中并且该图合法,任意点都指向编号大于自己的其他点,然后将数据拉满 T = 8 , n = 2000 T = 8, n = 2000 T=8,n=2000 即可。
hack样例

代码

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

const int N = 2023;
char mp[N][N];

int vis[N], n;
bool flag;
vector<int>g[2][N];

bool check(int op){
    for(int i = 1; i <= n; i ++){
        for(int j = 0; j < g[op][i].size(); j ++){
            int u = g[op][i][j];
            for(int k = 0; k < g[op][u].size(); k ++){
                int v = g[op][u][k];
                if(op == 0 && mp[i][v] != 'Q') return true;
                if(op == 1 && mp[i][v] != 'P') return true;
            }
        }
    }
    return false;
}
void solve(){
    scanf("%d",&n);
    for(int i = 1; i <= n; i ++){
        scanf("%s", mp[i] + 1);
        g[0][i].clear();
        g[1][i].clear();
    }

    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= n; j ++){
            if(mp[i][j] == '-') continue ;
            g[mp[i][j] == 'P'][i].push_back(j);
        }
    }
    if(check(1) || check(0)) puts("N");
    else puts("T");
}

int main(){
    int t;
    scanf("%d",&t);
    while(t --){
        solve();
    }
    return 0;
}

bitset优化暴力

可以看这位老哥的 WA是一笔财富

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/482074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【玩转Git三剑客笔记】第一章 Git基础

第一章 Git基础 1.综述2.安装Git3.使用Git之前需要做的最小配置4.创建第一个仓库并配置local用户信息1.创建Git仓库2.设置Git最小配置 5.通过几次commit来认识工作区和暂存区1.将工作区中所有已经被git追踪的文件一起添加到暂存区2.git log查看提交日志 6.给文件重命名的简便方…

密码学【java语言】初探究

文章目录 前言一 密码学1.1 古典密码学1.1.1 替换法1.1.2 移位法1.1.3 古典密码破解方式 二 近代密码学2.1 现代密码学2.1.1 散列函数2.1.2 对称密码2.1.3 非对称密码 二 凯撒加密的实践2.1 基础知识&#xff1a;ASCII编码2.2 ascii编码演示2.3 凯撒加密和解密实践2.4 频率分析…

安装Ubuntu22.04虚拟机的一些常见问题解决方法

文章目录 VirttalBox 开启共享剪切板文件夹、拖放的功能VirtualBox 安装 ubuntu后安装增强工具无效的解决办法解决ubuntu您没有权限查看“ 某某文件夹”的内容所需的权限linux更换源的两种方法[如何在 Ubuntu 20.04 上安装 Visual Studio Code - ](https://zhuanlan.zhihu.com/…

【Java入门合集】第二章Java语言基础(二)

【Java入门合集】第二章Java语言基础&#xff08;二&#xff09; 博主&#xff1a;命运之光 专栏JAVA入门 学习目标 掌握变量、常量、表达式的概念&#xff0c;数据类型及变量的定义方法&#xff1b; 掌握常用运算符的使用&#xff1b; 掌握程序的顺序结构、选择结构和循环结构…

权限提升:不带引号服务路径 || 不安全的服务权限.

权限提升&#xff1a;不带引号服务路径 || 不安全的服务权限. 权限提升简称提权&#xff0c;由于操作系统都是多用户操作系统&#xff0c;用户之间都有权限控制&#xff0c;比如通过 Web 漏洞拿到的是 Web 进程的权限&#xff0c;往往 Web 服务都是以一个权限很低的账号启动…

Nature:李龙等揭示抑郁症模型中社交压力阻断社交奖赏的神经环路机制

在人类社会中&#xff0c;社会压力尤其是创伤性社会经历会导致抑郁症、社交焦虑及创伤后应激障碍等多种精神疾病【1】。在抑郁症研究领域&#xff0c;有研究表明社会创伤会损害大脑负责奖赏的脑区功能&#xff0c;使社交活动变得不再有奖赏性&#xff0c;从而导致严重的社交回避…

【ShenYu系列】ShenYu Dubbo插件全流程源码解析

网关启动 在ShenyuConfiguration注入ShenyuWebHandler。 Bean("webHandler")public ShenyuWebHandler shenyuWebHandler(final ObjectProvider<List<ShenyuPlugin>> plugins, final ShenyuConfig config, Lazy final ShenyuLoaderService shenyuLoaderS…

初识Go语言20-包与工程化【用go mod管理工程、包引入规则、init调用链、可见性】

文章目录 包与工程化用go mod管理工程包引入规则init调用链可见性 包与工程化 用go mod管理工程 初始化项目: go mod init $module_name$module_name和目录名可以不一样。上述命令会生成go.mod文件&#xff0c;该文件内容形如&#xff1a; module go-coursego 1.17require (…

HarmonyOS服务卡片开发-文件组织与配置学习

HarmonyOS服务卡片开发-文件组织与配置学习 1.文件组织 目录结构 JS服务卡片(entry/src/main/js/Component)的典型开发目录结构如下&#xff1a; 目录结构中文件分类如下&#xff1a; .hml结尾的HML模板文件&#xff0c;这个文件用来描述卡片页面的模板布局结构。 .css结…

云计算(Cloud Computing)

一、从技术概念理解云计算 早期的云计算就是虚拟化主机上的分布式计算&#xff0c;现阶段的云计算&#xff0c;已经不单单是一种分布式计算&#xff0c;而是分布式计算、效用计算、负载均衡、并行计算、网络存储、热备份冗杂和虚拟化等计算机技术混合演进并跃升的结果。云计算…

飞书接入ChatGPT,打造属于自己的智能问答助手

文章目录 前言环境列表视频教程1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 转载自远控源码文章&#xff1a;飞书接入ChatGPT - 将ChatGPT集…

太酷了,库昊

昨天晚上凌晨3点30&#xff0c;勇士和国王的第7场比赛开打。 在上一局在勇士主场干翻勇士后&#xff0c;国王队的信心倍增&#xff0c;他们用自己的节奏一次次击溃勇士&#xff0c;特别是今天的前两节&#xff0c;国王能能够回应勇士的进球&#xff0c;防守也更有侵略性。今天不…

Spring第九阶段:Spring的注解功能

注解功能 1、注解配置Dao、Service、Controller组件 通过注解分别创建Dao、Service、Controller Spring配置bean的常用注解有 Controller 配置web层的组件 Service 配置Service组件 Repository 配置Dao组件 Component 配置JavaBean( 除Service , Dao , Controller组件之外的…

台积电和三星都变脸了,美国图谋失败,外媒:拜登心都碎了

美国的图谋甚大&#xff0c;然而美国的图谋却又如此迅速的浮现&#xff0c;看穿美国图谋的台积电和三星两家芯片企业如今不干了&#xff0c;这将破坏美国的计划&#xff0c;让美国无可奈何。 一、美国精心编织的大网 从数年前开始&#xff0c;美国就要求台积电和三星上交机密数…

想学编程但没有好的资料 来这 Python 爬取信息并写入数据,最详细教程

提示一下&#xff1a;我这个中一些用import引用的软件包&#xff0c;你们小白记得要下载哟 不然的话会报错的哟&#xff01; 下载软件包很简单的! 话不多说&#xff0c;直接开始… from selenium.webdriver.common.by import By from selenium import webdriver import re, …

5月2日第壹简报,星期二,农历三月十三

5月2日第壹简报&#xff0c;星期二&#xff0c;农历三月十三坚持阅读&#xff0c;静待花开1. “港车北上”政策公布&#xff1a;6月1日起接受申请&#xff0c;7月1日起可驶入广东&#xff0c;将惠及45万香港车主。2. 全球女性第一人&#xff01;董红娟登顶全部14座8000米级高峰…

nvm 安装 node,配置 yarn,cnpm

nvm 安装 node&#xff0c;配置 yarn, cnpm nvmnodeyarncnpm nvm 是什么&#xff1f;nodejs 的版本管理工具&#xff0c;为了解决 node.js 各种版本存在不兼容现象可以通过它安装和切换不同版本的 node.js重要&#xff1a;完全卸载本地 node下载链接 卸载完成之后&#xff0c;…

初识C++之智能指针

目录 一、智能指针的概念 二、RAII 三、 智能指针的拷贝构造 1. 智能指针的拷贝构造问题 2. C库中的智能指针 2.1 auto_ptr 2.2 unique_ptr 2.3 shared_pt 2.4 weak_ptr 四、shared_ptr的循环引用问题 五、 定制删除器 一、智能指针的概念 在了解智能指针的概念前&…

Java连接与操作Perforce

对于源码控管的基本使用来说&#xff0c; 使用Perforce的客户端工具就可以了&#xff0c; 但是某些应用场景下可能需要使用代码来与Perforce服务器进行交互&#xff0c; 比如&#xff1a; 自动部署流程中的自动取代码&#xff08;该场景一般也可以使用P4命令行工具实现&#x…

Windows共享内存与死锁

实验一 一、实验内容或题目&#xff1a; 利用共享内存完成一个生产者进程和一个消费者进程的同步。 二、实验目的与要求&#xff1a; 1、编写程序&#xff0c;使生产者进程和消费者进程通过共享内存和mutex来完成工作同步。 2、了解通过操作系统接口调用&#xff0c;实现通…