题目大概是,每个人收到信息后会把信息发给他认识的一个人如此下去,问一开始要把信息发送给谁这样看到信息的人数最多。
- 首先找出图中的SCC并记录每个SCC里面的点数,如果传到一个SCC,那么里面的人都可以看到信息。
- 然后SCC缩点后就形成DAG,直接记忆化搜索,d(u)搜索从u点出发开始传最多能传多少人。
- 最后就是找答案了。
1 #include2 #include 3 #include 4 using namespace std; 5 #define MAXN 55555 6 #define MAXM 55555 7 8 struct Edge{ 9 int u,v,next;10 }edge[MAXM];11 int NE,head[MAXN];12 void addEdge(int u,int v){13 edge[NE].u=u; edge[NE].v=v; edge[NE].next=head[u];14 head[u]=NE++;15 }16 17 int size[MAXN],bn,belong[MAXN];18 int stack[MAXN],top;19 bool instack[MAXN];20 int dn,dfn[MAXN],low[MAXN];21 void tarjan(int u){22 dfn[u]=low[u]=++dn;23 stack[++top]=u; instack[u]=1;24 for(int i=head[u]; i!=-1; i=edge[i].next){25 int v=edge[i].v;26 if(dfn[v]==0){27 tarjan(v);28 low[u]=min(low[u],low[v]);29 }else if(instack[v]){30 low[u]=min(low[u],dfn[v]);31 }32 }33 if(dfn[u]==low[u]){34 int v; ++bn;35 do{36 v=stack[top--];37 instack[v]=0;38 belong[v]=bn;39 ++size[bn];40 }while(u!=v);41 }42 }43 44 int d[MAXN];45 int dfs(int u){46 if(d[u]) return d[u];47 int res=size[u],tmp=0;48 for(int i=head[u]; i!=-1; i=edge[i].next){49 int v=edge[i].v;50 tmp=max(tmp,dfs(v));51 }52 return d[u]=res+tmp;53 }54 55 int main(){56 int t,n,a,b;57 scanf("%d",&t);58 for(int cse=1; cse<=t; ++cse){59 NE=0;60 memset(head,-1,sizeof(head));61 scanf("%d",&n);62 for(int i=0; i