我们首先由破坏力较大的武器向破坏力较小的武器建边,然后对于每个武器,从自己开始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; }
这个写法应该比官方题解门槛低一点吧(逃