我们首先由破坏力较大的武器向破坏力较小的武器建边,然后对于每个武器,从自己开始DFS,对于每个搜到的点,说明当前武器比搜索到的大,标记一下即可

#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
int read()
{
   int s=0,bj=0;
   char ch=getchar();
   while(ch<'0'||ch>'9')bj|=(ch=='-'),ch=getchar();
   while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
   return bj?-s:s;
}
void printnum(int x)
{
    if(x>9)printnum(x/10);
    putchar(x%10^48);
}
void print(int x,char ch)
{
    if(x<0){putchar('-');x=-x;}
    printnum(x);putchar(ch);
}
int n,m,num[2005];
struct node{int nx,to;}w[2005];int h[1005],cnt;
void AddEdge(int x,int y){w[++cnt].to=y;w[cnt].nx=h[x];h[x]=cnt;}
bool vst[1005][1005];//vst[i][j]标记i是否比j破坏力大 
void DFS(int x,int bj)
{
    for(int i=h[x];i;i=w[i].nx)
    {
        int y=w[i].to;
        if(!vst[bj][y]){vst[bj][y]=1;++num[y];DFS(y,bj);}//剪枝,防止搜索到重复的地方 
    }
}
int main()
{
    int x,y;
    n=read();m=read();
    for(int i=1;i<=m;++i)
    {
        x=read();y=read();
        AddEdge(x,y);
    }
    for(int i=1;i<=n;++i)DFS(i,i);//以每个点为起点进行搜索 
    for(int i=1;i<=n;++i)print(num[i],'\n');
    return 0;
}

这个写法应该比官方题解门槛低一点吧(逃