题目链接

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. java 控制台输入

    import java . util . Scanner ; public class Test { public static void main(String[] args) { Scanner ...

  2. 在caffe-ssd的环境搭建中遇到报错信息:Makefile:588: recipe for target '.build_release/cuda/src/caffe/layers/softmax_loss_layer.o' failed

    错误原因: 1.计算机没有安装GPU 2.有GPU但是NVCCFLAGS设置错误 解决方法: 1.对没有GPU的计算机,需要将Makefile中的CPU之前的#注释去掉,是的caffe运行的处理器进行 ...

  3. 十一 JS继承

    // time:2016.2.1 // des:继承 function Enemy() { this.level = 50; console.log("Enemy constructor&q ...

  4. 详解 ManualResetEvent(转)

    原文:http://www.cnblogs.com/li-peng/p/3291306.html 今天详细说一下ManualResetEvent 它可以通知一个或多个正在等待的线程已发生事件,允许线程 ...

  5. oracle 排序 row_number() over(partition by 排序字段)

    业务描述:按t.truckId,t.riskCode 分组,每个分组里有分数,取分组中分数最大的那条记录. 如:A1 B1   5  6 A1  B1   5  3 A1  B2   2  5 A1 ...

  6. 【Elasticsearch学习之二】Elasticsearch Rest风格操作

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 elasticsearch-2.2.0 一.Rest简介Re ...

  7. 转:Process类的使用

    转载自:http://www.oschina.net/code/snippet_119226_6188 一.根据进程名获取进程的用户名? 需要添加对 System.Management.dll 的引用 ...

  8. document.createDocumentFragment 以及创建节点速度比较

    document.createDocumentFragment document.createDocumentFragment()方法创建一个新空白的DocumentFragment对象. Docum ...

  9. vue路由6:导航钩子

    <div id="app"> <div> <router-link to="/">首页</router-link> ...

  10. centos 文件新建、删除、移动、复制等命令

    创建目录 mkdir 文件名 mkdir /var/www/test cp复制命令 cp命令复制文件从一个位置到另一位置.如果目的地文件存在,将覆复写该文件: 如果目的地目录存在,文件将复制到该目录下 ...