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

相关文章

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

hdu 1285(拓扑排序)

题意: 给各个队间的胜负关系,让排名次,名词相同按从小到大排。 解析: 拓扑排序是应用于有向无回路图(Direct Acyclic Graph,简称DAG)上的一种排序方式,对一个有向无回路图进行拓扑排序后,所有的顶点形成一个序列,对所有边(u,v),满足u 在v 的前面。该序列说明了顶点表示的事件或状态发生的整体顺序。比较经典的是在工程活动上,某些工程完成后,另一些工程才能继续,此时

poj 1182 并查集 食物链类

题意: 有n只动物,分别编号1....n。所有动物都属于A,B,C中的一种,已知A吃B,B吃C,C吃A。 按顺序给出下面两种共K条信息: 1. x 和 y 属于同一类。 2. x 吃 y 。 然而这些信息可能会出错,有可能有的信息和之前给出的信息矛盾,也有的信息可能给出的 x 和 y 不在n的范围内。 求k条信息中有多少条是不正确的。 解析: 对于每只动物,创建3个元素 i

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

Codeforces Round #261 (Div. 2)小记

A  XX注意最后输出满足条件,我也不知道为什么写的这么长。 #define X first#define Y secondvector<pair<int , int> > a ;int can(pair<int , int> c){return -1000 <= c.X && c.X <= 1000&& -1000 <= c.Y && c.Y <= 1000 ;}int m

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

Codeforces 482B 线段树

求是否存在这样的n个数; m次操作,每次操作就是三个数 l ,r,val          a[l] & a[l+1] &......&a[r] = val 就是区间l---r上的与的值为val 。 也就是意味着区间[L , R] 每个数要执行 | val 操作  最后判断  a[l] & a[l+1] &......&a[r] 是否= val import ja