LightOJ1417 Forwarding Emails(强连通分量+缩点+记忆化搜索)
题目大概是,每个人收到信息后会把信息发给他认识的一个人如此下去,问一开始要把信息发送给谁这样看到信息的人数最多。
- 首先找出图中的SCC并记录每个SCC里面的点数,如果传到一个SCC,那么里面的人都可以看到信息。
- 然后SCC缩点后就形成DAG,直接记忆化搜索,d(u)搜索从u点出发开始传最多能传多少人。
- 最后就是找答案了。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 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<n; ++i){ 63 scanf("%d%d",&a,&b); 64 addEdge(a,b); 65 } 66 67 top=bn=dn=0; 68 memset(instack,0,sizeof(instack)); 69 memset(dfn,0,sizeof(dfn)); 70 memset(size,0,sizeof(size)); 71 for(int i=1; i<=n; ++i){ 72 if(dfn[i]==0) tarjan(i); 73 } 74 75 int tmp=NE; NE=0; 76 memset(head,-1,sizeof(head)); 77 for(int i=0; i<tmp; ++i){ 78 int u=belong[edge[i].u],v=belong[edge[i].v]; 79 if(u==v) continue; 80 addEdge(u,v); 81 } 82 83 memset(d,0,sizeof(d)); 84 int mx=0; 85 for(int i=1; i<=bn; ++i){ 86 mx=max(mx,dfs(i)); 87 } 88 for(int i=1; i<=n; ++i){ 89 if(d[belong[i]]==mx){ 90 printf("Case %d: %d\n",cse,i); 91 break; 92 } 93 } 94 } 95 return 0; 96 }