Codeforces Round #541 (Div. 2)D. Gourmet choice(拓扑排序+并查集+思维)

2024-04-18 06:48

本文主要是介绍Codeforces Round #541 (Div. 2)D. Gourmet choice(拓扑排序+并查集+思维),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接:https://codeforces.com/contest/1131/problem/D

 

题目大意:给出n个数和m个数之间分别的大小关系,求使得最大数最小的情况

 

题目思路:如果全是>或者<这道题很简单,直接建图就结束了,但是这里有个=。这个等于的解决非常巧妙,使用并查集将=的点并在一起缩点然后这道题就转换成了只有>或<的情况

 

以下是代码:

#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define per(i,a,b) for(ll i=a;i>=b;i--)
#define ll long long
const ll MAXN = 2e3+5;
const ll MOD = 1e9+7;
int n,m,a[MAXN],vis[MAXN],pre[MAXN];
vector<int>v[MAXN];
char mp[MAXN][MAXN];
struct node{int x,val;
}p;
queue<node>q;
int Find(int x){return pre[x]==x?x:pre[x]=Find(pre[x]);
}
int main()
{while(~scanf("%d%d",&n,&m)){int flag=0;memset(vis,0,sizeof(vis));memset(a,0,sizeof(a));rep(i,1,n+m)pre[i]=i;rep(i,1,n){scanf("%s",mp[i]+1);}rep(i,1,n){rep(j,1,m){if(mp[i][j]=='='){int xx=Find(i),yy=Find(n+j);pre[xx]=yy;}}}rep(i,1,n){rep(j,1,m){if(mp[i][j]=='=')continue;int xx=Find(i),yy=Find(n+j);if(xx==yy){flag=1;break;}if(mp[i][j]=='<'){v[xx].push_back(yy);vis[yy]++;}if(mp[i][j]=='>'){v[yy].push_back(xx);vis[xx]++;}}if(flag)break;}if(flag){puts("No");continue;}rep(i,1,n){if(vis[i]==0){p.x=i,p.val=1;q.push(p);}}rep(i,1,m){if(vis[n+i]==0){p.x=n+i,p.val=1;q.push(p);}}int tot=0;while(!q.empty()){tot++;p=q.front();q.pop();a[p.x]=p.val;int len=v[p.x].size();rep(i,0,len-1){int to=v[p.x][i];vis[to]--;if(!vis[to]){node temp;temp.x=to,temp.val=p.val+1;q.push(temp);}}}rep(i,1,n+m){a[i]=a[Find(i)];}rep(i,1,n){rep(j,1,m){if((mp[i][j]=='='&&a[i]==a[n+j])||(mp[i][j]=='>'&&a[i]>a[n+j])||(mp[i][j]=='<'&&a[i]<a[n+j]))flag=0;else{flag=1;break;}}if(flag)break;}if(flag)printf("No\n");else{printf("Yes\n");rep(i,1,n+m){printf("%d",a[i]);if(i==n||i==n+m)cout<<endl;else cout<<" ";}}}return 0;
}

 

这篇关于Codeforces Round #541 (Div. 2)D. Gourmet choice(拓扑排序+并查集+思维)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/914045

相关文章

如何突破底层思维方式的牢笼

我始终认为,牛人和普通人的根本区别在于思维方式的不同,而非知识多少、阅历多少。 在这个世界上总有一帮神一样的人物存在。就像读到的那句话:“人类就像是一条历史长河中的鱼,只有某几条鱼跳出河面,看到世界的法则,但是却无法改变,当那几条鱼中有跳上岸,进化了,改变河道流向,那样才能改变法则。”  最近一段时间一直在不断寻在内心的东西,同时也在不断的去反省和否定自己的一些思维模式,尝试重

随想录 Day 69 并查集 107. 寻找存在的路径

随想录 Day 69 并查集 107. 寻找存在的路径 理论基础 int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好vector<int> father = vector<int> (n, 0); // C++里的一种数组结构// 并查集初始化void init() {for (int i = 0; i < n; ++i) {father[i] = i;}

数据结构9——排序

一、冒泡排序 冒泡排序(Bubble Sort),顾名思义,就是指越小的元素会经由交换慢慢“浮”到数列的顶端。 算法原理 从左到右,依次比较相邻的元素大小,更大的元素交换到右边;从第一组相邻元素比较到最后一组相邻元素,这一步结束最后一个元素必然是参与比较的元素中最大的元素;按照大的居右原则,重新从左到后比较,前一轮中得到的最后一个元素不参4与比较,得出新一轮的最大元素;按照上述规则,每一轮结

七种排序方式总结

/*2018.01.23*A:YUAN*T:其中排序算法:冒泡排序,简单排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序*/#include <stdio.h>#include <math.h>#include <malloc.h>#define MAXSIZE 10000#define FALSE 0#define TRUE 1typedef struct {i

拓扑排序——C语言

拓扑排序(Topological Sorting)是一种用于有向无环图(DAG)的排序算法,其输出是图中所有顶点的线性排序,使得对于每条有向边 (u, v),顶点 u 在 v 之前出现。拓扑排序确定了项目网络图中的起始事件和终止事件,也就是顶点的执行顺序。         因为是有向无环图,所以拓扑排序的作用其实就是把先发生的排序在前面,后发生的排序到后面。 例如现在我们有一个

嵌入式学习——数据结构(哈希、排序)——day50

1. 查找二叉树、搜索二叉树、平衡二叉树 2. 哈希表——人的身份证——哈希函数 3. 哈希冲突、哈希矛盾 4. 哈希代码 4.1 创建哈希表 4.2  5. 算法设计 5.1 正确性 5.2 可读性(高内聚、低耦合) 5.3 健壮性 5.4 高效率(时间复杂度)时间复杂度越低,效率越高, 5.5 低储存(空间复杂度)空间复杂度越低,存储空间越少 6.排序算法 6.1 冒

A bug‘s life 虫子的生活(带权并查集)

题目链接: 2492 -- A Bug's Life (poj.org) 题目描述: 思路: 带权并查集,处理方法基本与食物链(http://t.csdnimg.cn/fSnRr)相同,没什么思维创新 但是一开始WA了几次,有些细节没有注意好,还是需要静下心来,好好分析问题,需要警惕! 参考代码: //#include<bits/stdc++.h>#include<iostream

leetcode刷题(40)——83. 删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3->3 输出: 1->2->3 平时我们删除一个链表中的某个元素,一般都是以下的写法: temp.next = temp.next.next; 这样temp.next就被删除了 此题解法如下: class Solution

Codeforces 158B

很久没有刷题了,刚刚有小学弟问了这道题,AC之后贴上来吧。水~~~ #include <cstdio>#include <cmath>int main() {int n;while(scanf("%d", &n) != EOF) {int a = 0, b = 0, c = 0, d = 0;int arr[100001];for (int i = 0; i < n; ++