#
我们能知道某cow的排名当且仅当知道它前面有多少,后面有多少
#
知道前面有多少?
建边的时候建一点指向比它强的人的边。
相当于问多少点和该点联通。
这个是最短路可以解决的事情(我猜也许拓扑排序也可
#
那后面呢?
反向建边
#如果n变得很大呢?
那就只能用dij,可那就变成了非多源最短路了。
也许不能兼得吧。(大数据学生不服.
---
第一遍的时候re了,因为m=4500,是大于我设置的maxn的。
mark.
#include <iostream> #include <math.h> #include <string.h> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <algorithm> #include <cstdio> using namespace std; const int maxn=1e5; int n,m,win[maxn],lose[maxn],ans1[maxn],ans2[maxn],d[300][300]; int main( ) { //freopen("lys.in","r",stdin); cin>>n>>m; memset(d,0,sizeof(d)); for(int i=1;i<=m;i++) { cin>>win[i]>>lose[i]; d[lose[i]][win[i]]=1; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(d[i][k]==1&&d[k][j]==1) { d[i][j]=1; } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) continue; if(d[i][j]==1) { ans1[i]++; } } } memset(d,0,sizeof(d)); for(int i=1;i<=m;i++) { d[win[i]][lose[i]]=1; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(d[i][k]==1&&d[k][j]==1) { d[i][j]=1; } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) continue; if(d[i][j]==1) { ans2[i]++; } } } int ans=0; for(int i=1;i<=n;i++) { if(ans1[i]+ans2[i]==n-1) { ans++; } } printf("%d",ans); }