【DFS】【枚舉】Gym - 101246G - Revolutionary Roads
阿新 • • 發佈:2017-07-14
brush pre void pri push include inpu eof nss
給你一張有向圖,問你將任意一條邊變成雙向後,所能得到的最大強連通分量的大小。
縮點之後,預處理can(i,j)表示i能到j。
之後枚舉每一條邊(u,v),再枚舉其他所有點t,如果can(u,t) && can(t,v),則t能和u、v共在一個強連通分量,嘗試更新答案。
#include<cstdio> #include<algorithm> #include<vector> #include<cstring> using namespace std; bool can[1010][1010]; struct Edge{ int id,v; }; vector<Edge>G[1010],G2[1010]; vector<int>vs,rG[1010]; int n,m,K; bool used[1010]; void dfs(int U){ used[U]=1; for(int i=0;i<G[U].size();++i){ if(!used[G[U][i].v]){ dfs(G[U][i].v); } } vs.push_back(U); } int cmp[1010]; void rdfs(int U){ used[U]=1; cmp[U]=K; for(int i=0;i<rG[U].size();++i){ if(!used[rG[U][i]]){ rdfs(rG[U][i]); } } } int a[1010],ans; void dfs3(int rt,int U){ can[rt][U]=1; for(int i=0;i<G2[U].size();++i){ if(!can[rt][G2[U][i].v]){ dfs3(rt,G2[U][i].v); } } } int p,anss[20010]; int main(){ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); int x,y; scanf("%d%d",&n,&m); for(int i=1;i<=m;++i){ scanf("%d%d",&x,&y); G[x].push_back((Edge){i,y}); rG[y].push_back(x); } for(int i=1;i<=n;++i){ if(!used[i]){ dfs(i); } } memset(used,0,sizeof(used)); for(int i=vs.size()-1;i>=0;--i){ if(!used[vs[i]]){ ++K; rdfs(vs[i]); } } for(int i=1;i<=n;++i){ ++a[cmp[i]]; } for(int i=1;i<=K;++i){ ans=max(ans,a[i]); } for(int i=1;i<=m;++i){ anss[i]=i; } p=m; for(int i=1;i<=n;++i){ for(int j=0;j<G[i].size();++j){ if(cmp[i]!=cmp[G[i][j].v]){ G2[cmp[i]].push_back((Edge){G[i][j].id,cmp[G[i][j].v]}); } } } for(int i=1;i<=K;++i){ dfs3(i,i); } for(int i=1;i<=K;++i){ for(int j=0;j<G2[i].size();++j){ int tmp=a[i]+a[G2[i][j].v]; for(int l=1;l<=K;++l){ if(l!=i && l!=G2[i][j].v && can[i][l] && can[l][G2[i][j].v]){ tmp+=a[l]; } } if(tmp>ans){ p=1; anss[p]=G2[i][j].id; ans=tmp; } else if(tmp==ans){ anss[++p]=G2[i][j].id; } } } sort(anss+1,anss+p+1); printf("%d\n%d\n",ans,p); for(int i=1;i<p;++i){ printf("%d ",anss[i]); } if(p){ printf("%d\n",anss[p]); } return 0; }
【DFS】【枚舉】Gym - 101246G - Revolutionary Roads