M. My University Is Better Than Yours
题目描述
People rank for things. Yes, ranking is nothing for most of the time, except when you are doing year-end report to your boss.
Under the promotion of the construction of world-class universities, a lot of universities are struggling to improve ranking in every way. Publishing papers, applying for funds, improving diversity… They are too hard and your result may not be fairly judged by institutions like US News and Times! However, some universities are more clever – they publish their own rankings, which makes the ranking indirectly better. For example, using Shanghai Ranking’s Academic Ranking of World Universities (ARWU) produced by Shanghai Jiao Tong University, Desprado2 can prove that his school is better than MIT.
Anyway, that is a joke unless you are finding jobs and need to brag about your school. But at the same time, Desprado2 comes out a problem: assume there are
n
n
n universities in total, and he has collected m university rankings. For simplicity, all the universities are denoted by a number from
1
1
1 to
n
n
n. Here, Desprado2 defines that university
x
x
x is directly better than university y, if and only if there exists a university ranking such that university
x
x
x ranks higher than university
y
y
y. Furthermore, Desprado2 defines that university
x
x
x is
b
e
t
t
e
r
better
better than university
y
y
y, if and only if there exists a sequence {s1, s2, …, sk} (k≥2), such that:
s
1
=
x
,
s
k
=
y
s_1=x, s_k=y
s1=x,sk=y
∀i∈{1,2,…,k−1}, university si is directly better than university
s
i
+
1
s_{i+1}
si+1
For each university, Desprado2 want you to tell him it is better than how many of other universities.
输入描述
The first line contains two integers n n n and m ( 1 ≤ n ≤ 5 × 1 0 5 , 1 ≤ m ≤ 5 × 1 0 5 , 1 ≤ n × m ≤ 1 0 6 ) m (1≤n≤5×10^5, 1≤m≤5×10^5, 1≤n×m≤10^6) m(1≤n≤5×105,1≤m≤5×105,1≤n×m≤106), denoting the number of universities considered, and the number of university rankings.
Then follows m m m lines. The i i i-th line contains n distinct integers s i , 1 , s i , 2 , . . . , s i , n si,1, si,2, ..., si,n si,1,si,2,...,si,n ( 1 ≤ s i , j ≤ n ) (1≤si,j≤n) (1≤si,j≤n), denoting the order of the i i i-th university ranking (from high to low).
输出描述
Output one line with n n n integers a 1 , a 2 , … , a n a1,a2,…,an a1,a2,…,an, separated by spaces. The i i i-th number a i a_i ai denotes the number of universities that university i i i is better than.
输入样例1:
4 21 2 3 4
1 3 2 4
输出样例1:
3 2 2 0输入样例2:
4 21 2 3 4
4 3 2 1
输出样例2:
3 3 3 3输入样例3:
5 25 4 3 2 1
5 4 3 2 1
输出样例3:
0 1 2 3 4思路
题目中的直接大于意味着大于这所学校即大于这所学校所大于的所有学校 故我们可以将相邻的两所学校连边建图 再缩点将图转化为 D A G DAG DAG 图 设每个点权值为 1 1 1 求以每个点为首除去自身点的最大权值路径 d p [ i ] dp[i] dp[i]
Code
#include<bits/stdc++.h>
using namespace std;
#define __T int csT;scanf("%d",&csT);while(csT--)
const int mod=998244353;
const int maxn=5e5+3;
const int maxm=1e6+3;
//Kosaraju:O(n+m)
//需建新图的情况 加上fr[maxn]代表fr[x]属于哪个强连通分量
//并且需要记录原始边 u[] v[]
int n,m,cnt,flcnt;//flcnt 新点/强连通分量个数
int stcnt,st[maxn];//模拟栈 存储逆后序
int h[maxn],rh[maxn];//正反图
int nm,nh[maxn],na[maxn];//新图
int a[maxn],vis[maxn],fr[maxn],dp[maxn];
int u[maxm],v[maxm];//原始边
struct node
{
int to,nx;
}e[maxm],re[maxm],ne[maxm];
void dfs1(int at)
{
if(vis[at]==1)return;
vis[at]=1;
for(int i=h[at];~i;i=e[i].nx)
{
dfs1(e[i].to);
}
st[++stcnt]=at;
}//先跑一遍正图以得到跑反图时的顺序序列
void dfs2(int at,int id)
{
if(vis[at]==2)return;
vis[at]=2;
fr[at]=id;
na[id]+=a[at];//统计该强连通分量的权值和
for(int i=rh[at];~i;i=re[i].nx)
{
dfs2(re[i].to,id);
}
}
void dfs3(int at)
{
if(dp[at]!=-1)return;
dp[at]=0;
for(int i=nh[at];~i;i=ne[i].nx)
{
dfs3(ne[i].to);
dp[at]=max(dp[at],dp[ne[i].to]);
}
dp[at]+=na[at];
}
inline void sol()
{
scanf("%d%d",&n,&m);
memset(h,-1,sizeof h);
memset(rh,-1,sizeof rh);
memset(nh,-1,sizeof nh);
memset(vis,0,sizeof vis);
memset(na,0,sizeof na);
stcnt=cnt=nm=flcnt=0;
for(int i=1;i<=n;++i)
{
a[i]=1;
}
int q,x,mcnt=0;
for(int i=0;i<m;++i)
{
q=-1;
for(int j=1;j<=n;++j)
{
scanf("%d",&x);
if(q==-1)
{
q=x;
continue;
}
u[++mcnt]=q;
v[mcnt]=x;
e[++cnt].to=v[mcnt];
e[cnt].nx=h[u[mcnt]];
h[u[mcnt]]=cnt;
re[cnt].to=u[mcnt];
re[cnt].nx=rh[v[mcnt]];
rh[v[mcnt]]=cnt;//建正图反图
q=x;
}
}
for(int i=1;i<=n;++i)
{
if(vis[i]==0)dfs1(i);
}
for(int i=n;i>=1;--i)
{
if(vis[st[i]]==1)
{
dfs2(st[i],++flcnt);
}
}
for(int i=1;i<=mcnt;++i)
{
if(fr[u[i]]!=fr[v[i]])//筛去缩点后的自环
{
ne[++nm].to=fr[v[i]];
ne[nm].nx=nh[fr[u[i]]];
nh[fr[u[i]]]=nm;
}
}
memset(dp,-1,sizeof dp);
for(int i=1;i<=flcnt;++i)
{
if(dp[i]==-1)
{
dfs3(i);
}
}
for(int i=1;i<=n;++i)
{
printf("%d ",dp[fr[i]]-1);
}
puts("");
}
int main()
{
//__T
sol();
return 0;
}