题目链接

541div2

http://codeforces.com/contest/1131/problem/D

思路

给出n序列和m序列的相对大小关系

构造出最大值最小的序列

缩点+拓扑

小的向大的连边

相等的连个环

tarjan缩点,判断环内是否ok

最后拓扑

更新要这样

ans[v]=max(ans[v],ans[u]+1);

就是说取最后更新的一个,保证大小关系

代码

#include <bits/stdc++.h>
#define ll long long
#define iter vector<int>::iterator
using namespace std;
const int N=2007;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int M[N][N];
int n,m;
struct node {
int v,nxt;
}e[N*N];
int head[N*N],tot;
void add(int u,int v) {
// cout<<u<<" "<<v<<"\n";
e[++tot].v=v;
e[tot].nxt=head[u];
head[u]=tot;
}
vector<int> G[N],col[N];
char s[N];
int dfn[N],low[N],stak[N],top,vis[N],cnt,js,belong[N],rt[N];
int ans[N],ru[N];
void tarjan(int u) {
dfn[u]=low[u]=++cnt;
vis[u]=1;
stak[++top]=u;
for(iter v=G[u].begin();v!=G[u].end();++v) {
if(!dfn[*v]) {
tarjan(*v);
dfn[u]=min(dfn[u],dfn[*v]);
} else
if(vis[*v])
dfn[u]=min(dfn[u],low[*v]);
}
if(low[u]==dfn[u]) {
++js;
while(stak[top]!=u) {
vis[stak[top]]=0;
col[js].push_back(stak[top]);
belong[stak[top]]=js;
top--;
}
top--;
belong[u]=js;
vis[u]=0;
col[js].push_back(u);
}
}
queue<int> q;
int main() {
n=read(),m=read();
for(int i=1;i<=n;++i) {
scanf("%s",s+1);
for(int j=1;j<=m;++j) {
if(s[j]=='>') {
M[j+n][i]=1;
M[i][j+n]=-1;
G[j+n].push_back(i);
// cout<<j+n<<" "<<i<<"\n";
}
if(s[j]=='<') {
M[i][j+n]=1;
M[j+n][i]=-1;
G[i].push_back(j+n);
// cout<<i<<" "<<j+n<<"\n";
}
if(s[j]=='=') {
G[j+n].push_back(i);
G[i].push_back(j+n);
// cout<<j+n<<" "<<i<<"\n";cout<<i<<" "<<j+n<<"?\n";
}
}
}
// for(int i=1;i<=n+m;++i) {
// for(int j=1;j<=n+m;++j) {
// cout<<M[i][j]<<" ";
// }
// puts("");
// }
for(int i=1;i<=m+n;++i)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=js;++i) {
// cout<<col[i].size()<<"!\n";
for(iter a=col[i].begin();a!=col[i].end();++a) {
for(iter b=col[i].begin();b!=col[i].end();++b) {
// cout<<*a<<" "<<*b<<" ?\n";
if(M[*a][*b]!=0) {
// cout<<*a<<" "<<*b<<"\n";
cout<<"No";
return 0;
}
}
// cout<<*a<<" ";
}
// puts("");
}
// return 0;
for(int i=1;i<=n+m;++i) {
for(int j=1;j<=n+m;++j) {
if(M[i][j]==1)
if(belong[i]!=belong[j]) {
add(belong[i],belong[j]);
// cout<<belong[i]<<" "<<belong[j]<<"!!\n";
ru[belong[j]]++;
}
}
}
// memset(ans,0x3f,sizeof(ans));
for(int i=1;i<=js;++i) if(!ru[i]) q.push(i),ans[i]=1;
while(!q.empty()) {
int u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
ans[v]=max(ans[v],ans[u]+1);
ru[v]--;
if(!ru[v]) q.push(v);
}
}
// for(int i=1;i<=js;++i) cout<<ans[i]<<" ";cout<<"\n";return 0;
puts("Yes");
for(int i=1;i<=n;++i) printf("%d ",ans[belong[i]]);
puts("");
for(int i=1;i<=m;++i) printf("%d ",ans[belong[i+n]]);
return 0;
}
/*
3 3
<<<
<<=
<<=
*/

CF1131D tarjan,拓扑的更多相关文章

  1. 【bzoj1093】[ZJOI2007]最大半连通子图 Tarjan+拓扑排序+dp

    题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:对于u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. ...

  2. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  3. 【tarjan 拓扑排序 dp】bzoj1093: [ZJOI2007]最大半连通子图

    思维难度不大,关键考代码实现能力.一些细节还是很妙的. Description 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于 ...

  4. P3387缩点(tarjan+拓扑排序+线性dp)

    题目描述 给定一个 n个点 m 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 输入 ...

  5. [模板][Luogu3387] 缩点 - Tarjan, 拓扑+DP

    Description 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次 ...

  6. 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图

    https://www.luogu.org/problemnew/show/P1073 C国有 n n个大城市和 mm 条道路,每条道路连接这 nn个城市中的某两个城市.任意两个城市之间最多只有一条道 ...

  7. bzoj5017 炸弹 (线段树优化建图+tarjan+拓扑序dp)

    直接建图边数太多,用线段树优化一下 然后缩点,记下来每个点里有多少个炸弹 然后按拓扑序反向dp一下就行了 #include<bits/stdc++.h> #define pa pair&l ...

  8. BZOJ.2208.[JSOI2010]连通数(bitset Tarjan 拓扑)

    题目链接 先缩点,对于scc之间贡献即为szscc[i]*szscc[j] 用f[i][j]表示scci是否能到sccj 拓扑排序,每次把now的f或上to的f 用bitset优化 //63888kb ...

  9. bzoj 1093 最大半连通子图 - Tarjan - 拓扑排序 - 动态规划

    一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G'=(V ...

随机推荐

  1. Metasploit渗透技巧:后渗透Meterpreter代理

    Metasploit是一个免费的.可下载的渗透测试框架,通过它可以很容易地获取.开发并对计算机软件漏洞实施攻击测试.它本身附带数百个已知软件漏洞的专业级漏洞攻击测试工具. 当H.D. Moore在20 ...

  2. C#之Action的实际应用例子

    public class DemoAction{ public Action action; public Action<int> action1; public Action<in ...

  3. Nginx技术研究系列6-配置详解

    前两篇文章介绍了Nginx反向代理和动态路由: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 Ngnix技术研究系列2-基于Redis实现动态路由 随着研究的深入,很重要的一点就是了解 ...

  4. 【函数封装】javascript判断是否是微信浏览器

    //判断是否是微信浏览器的函数 function isWeiXin(){ //window.navigator.userAgent属性包含了浏览器类型.版本.操作系统类型.浏览器引擎类型等信息,这个属 ...

  5. svn安装使用

    SVN安装使用 获取项目 1.首先新建文件夹.如:测试项目. 2.接着鼠标右键选择:SVN Checkout/SVN 检出 3.在出行的对话框中输入仓库地址.如:svn://198.021.262/2 ...

  6. 【Alpha版本】冲刺阶段——Day5

    [Alpha版本]冲刺阶段--Day5 阅读目录 今日进展 问题困难 明日任务 今日贡献量 站立式会议 TODOlist [今日进展] 完成登录类代码 public void LOGIN() { co ...

  7. windows环境下 curl 安装和使用

    curl下载地址:https://curl.haxx.se/download.html,拉到页面最底下,选择红色选中的那个CAB的进行下载,如下图所示: 下载完成后,解压. 解决windows控制台c ...

  8. Step1:SQL Server 复制介绍

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 前言(Introduction) 复制逻辑结构图(Construction) 系列文章索引(Catalog) 总结&am ...

  9. 了解一下 Linux 上用于的 SSH 图形界面工具

    如果你碰巧喜欢好的图形界面工具,你肯定很乐于了解一些 Linux 上优秀的 SSH 图形界面工具.让我们来看看这三个工具,看看它们中的一个(或多个)是否完全符合你的需求. 在你担任 Linux 管理员 ...

  10. 栈的压入和弹出序列(剑指Offer)

    输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一 ...