HDU 3639 Hawk-and-Chicken 强连通缩点+搜索
来源:互联网 发布:d3.js可视化 编辑:程序博客网 时间:2024/05/21 17:32
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=3594
题意
n个人,为了争夺谁是胜者,出给一个游戏规则,每个人都可以支持其他人,如A可以支持B为胜者,这种支持可以传递,如:A->B->C则支持C有两个人,如果成环,那么环中每个人都获得环中其他人所有人的支持。试求出获得支持数最多的人,如果有多个,按从小到大的顺序输出其编号。
思路
首先是强连通分量缩点,缩点的权值为缩点内原图中点的个数。因为是DAG图,所以反向建图,从入度为0的点出发累加路径上所有点的权值,累加得到的数值最大的点-1即是最大支持数(因为同一个缩点内需要减去自己)然后找出缩点累加值为最大的缩点,输出缩点中原图的点。 具体看代码
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<vector>#include<string>#include<queue>#include<stack>#include<set>#include<map>#define ll long longusing namespace std;const int INF = ( 2e9 ) + 2;const ll maxn = 5010;vector<int> g[2][maxn];int dfn[maxn],low[maxn],Stack[maxn],Belong[maxn],dp[maxn],w[maxn];int index,top,scc;bool Instack[maxn],vis[maxn],In[maxn];void tarjan(int u){ int v; dfn[u]=low[u]=++index; Stack[top++]=u; Instack[u]=1; for(int i=0,L=g[0][u].size(); i<L; i++) { v=g[0][u][i]; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(Instack[v]) low[u]=min(low[u],low[v]); } if(dfn[u]==low[u]) { scc++; do { v=Stack[--top]; Belong[v]=scc; Instack[v]=0; w[scc]++; //缩点的权值为点中的个数 } while(v!=u); }}void getmap(int n){ memset(dfn,0,sizeof(dfn)); index=top=scc=0; for(int i=0; i<n; i++) if(!dfn[i])tarjan(i); for(int i=0; i<n; i++) { for(int j=0,L=g[0][i].size(); j<L; j++) { int v=g[0][i][j]; if(Belong[i]!=Belong[v]) { g[1][Belong[v]].push_back(Belong[i]); // 缩点图 :反向建的 In[Belong[i]]=1; } } }}int dfs(int u){ int sum=w[u]; vis[u]=1; for(int i=0,L=g[1][u].size(); i<L; i++) { int v=g[1][u][i]; if(vis[v])continue; sum+=dfs(v); } return sum;}void init(int n){ for(int i=0; i<=n; i++) { g[0][i].clear(); g[1][i].clear(); dp[i]=-INF; } memset(w,0,sizeof(w)); memset(In,0,sizeof(In));}int main(){ int T;// freopen("in.txt","r",stdin); scanf("%d",&T); for(int cas=1; cas<=T; cas++) { int n,m,u,v; scanf("%d%d",&n,&m); init(n); for(int i=0; i<m; i++) { scanf("%d%d",&u,&v); g[0][u].push_back(v); //原图 } getmap(n); int mx=-1,f=1; for(int i=1; i<=scc; i++) if(In[i]==0) // 从入度为0的点出发 ,累加所有可达点的权值 { memset(vis,0,sizeof(vis)); int sum = dfs(i); if(sum>mx) { mx=sum; } dp[i]=sum; } printf("Case %d: %d\n",cas,mx-1); // 答案最后为 mx-1 ,缩点内需要减去一个它本身 for(int i=0; i<n; i++) { if(dp[Belong[i]]==mx) { if(f) { printf("%d",i); f=0; } else printf(" %d",i); } } printf("\n"); }}
阅读全文
0 0
- HDU 3639 Hawk-and-Chicken 强连通缩点+搜索
- 【HDU】3639 Hawk-and-Chicken 强连通缩点+DFS
- Hawk-and-Chicken (hdu 3639 强连通缩点+反向建图DFS)
- HDU 3639 Hawk-and-Chicken(强连通分量+缩点)
- HDU 3639 Hawk-and-Chicken 强联通缩点 + DFS
- HDU 3639 Hawk-and-Chicken(强连通分量+缩点)
- HDU 3639 Hawk-and-Chicken(强连通分量+缩点)
- hdu 3639 (强连通缩点+搜索)
- HDU 3639 Hawk-and-Chicken(强连通)
- hdu 3639 Hawk-and-Chicken 强连通分量 targin
- HDU - 3639 Hawk-and-Chicken(dfs+强连通分量)
- HDU 3639Hawk-and-Chicken 强连通分量分解 + dfs
- hdu 3639 Hawk-and-Chicken【强联通Tarjan+Dfs】
- HDU 3639 Hawk-and-Chicken
- hdu 3639 Hawk-and-Chicken(缩点+树dp)
- HDU 3639 Hawk-and-Chicken(Tarjan缩点+反向DFS)
- HDU 3639 Hawk-and-Chicken tarjan缩点+dfs
- HDU 3639 强连通缩点优化
- javascript原型链
- 数据结构-二维数组-三角矩阵压缩存储
- C++基础(1)
- [HDU-1213]How Many Tables
- 用到了的一些Linux小命令
- HDU 3639 Hawk-and-Chicken 强连通缩点+搜索
- MVC
- SourceInsight使用
- 如何在浏览器中控制使用USB摄像头
- Server Tomcat v7.0 Server at localhost was unable to start within 45 seconds
- 在CENTOS7上玩转Ethereum区块链(4):实验前的准备工作
- 哈哈日语 日语入门学习需遵守这六项
- LinuxStudyNote(36)-Vim(1)-Vim常用操作、Vim操作详细教程、Vim常用命令、命令模式、命令模式常用命令、插入模式、编辑模式
- 正则表达式分组、断言详解