UVA11324 强连通+dp记忆化搜索
2015-09-10 21:22
295 查看
题意:对于一个有向图,问最大团中有多少点,要求该点集内所有点对间至少有一条路径(u到v或v到u或两条都有)。
首先,对于每一个强连通分量,其中的所有点必然能够互相到达,所以先进行缩点,然后对于缩点后的 DAG,dp[i] 表示从 i 强连通分量开始能够到达的最多的点数,那么在缩点时需要记录一下每个强连通分量的点数。然后进行DP,初始值定为该强连通分量的点数,然后用它能到达的点来更新它本身。取最大值就行了。
View Code
首先,对于每一个强连通分量,其中的所有点必然能够互相到达,所以先进行缩点,然后对于缩点后的 DAG,dp[i] 表示从 i 强连通分量开始能够到达的最多的点数,那么在缩点时需要记录一下每个强连通分量的点数。然后进行DP,初始值定为该强连通分量的点数,然后用它能到达的点来更新它本身。取最大值就行了。
#include<stdio.h> #include<string.h> #include<stack> #include<queue> using namespace std; const int maxn=1005; const int maxm=50005; int head[2][maxn],point[2][maxm],nxt[2][maxm],size[2]; int n,t,scccnt; int stx[maxn],low[maxn],scc[maxn],num[maxn],dp[maxn]; stack<int>S; void init(){ memset(head,-1,sizeof(head)); size[0]=size[1]=0; memset(dp,0,sizeof(dp)); } void add(int a,int b,int c=0){ point[c][size[c]]=b; nxt[c][size[c]]=head[c][a]; head[c][a]=size[c]++; } void dfs(int s){ stx[s]=low[s]=++t; S.push(s); for(int i=head[0][s];~i;i=nxt[0][i]){ int j=point[0][i]; if(!stx[j]){ dfs(j); low[s]=min(low[s],low[j]); } else if(!scc[j]){ low[s]=min(low[s],stx[j]); } } if(low[s]==stx[s]){ scccnt++; while(1){ int u=S.top();S.pop(); scc[u]=scccnt; num[scccnt]++; if(s==u)break; } } } void setscc(){ memset(stx,0,sizeof(stx)); memset(scc,0,sizeof(scc)); memset(num,0,sizeof(num)); t=scccnt=0; for(int i=1;i<=n;++i)if(!stx[i])dfs(i); for(int i=1;i<=n;++i){ for(int j=head[0][i];~j;j=nxt[0][j]){ int k=point[0][j]; if(scc[i]!=scc[k]){ add(scc[i],scc[k],1); } } } } void dfs1(int s){ if(dp[s])return; dp[s]=num[s]; for(int i=head[1][s];~i;i=nxt[1][i]){ int j=point[1][i]; dfs(j); if(num[s]+dp[j]>dp[s])dp[s]=num[s]+dp[j]; } } int main(){ int T; scanf("%d",&T); while(T--){ int m; scanf("%d%d",&n,&m); init(); while(m--){ int a,b; scanf("%d%d",&a,&b); add(a,b); } setscc(); int ans=0; for(int i=1;i<=scccnt;++i){ dfs1(i); if(ans<dp[i])ans=dp[i]; } printf("%d\n",ans); } return 0; }
View Code
相关文章推荐
- python库的安装方法
- USACO 1.2 Palindromic Squares (进制转换)
- android 4.1.2系统 phone 导入eclipse编译
- 文件操作中的几个大坑
- HDU 1098 Ignatius's puzzle 费马小定理+扩展欧几里德算法
- uva 12299 - RMQ with Shifts--- 线段树单点更新
- POJ - 1905-Expanding Rods-数论-二分&几何
- caffe for windows 模型中 solver.prototxt 代码解读
- C++Primer中文版 1.5.2节练习
- Mysql 查看连接数,状态
- 0910Android音乐播放器
- COCI CONTEST #3 29.11.2014 考后总结
- System中的一些属性(Properties属性)如何获取系统属性和指定系统属性
- 【C++面向对象学习笔记】-构造函数和析构函数
- [LeetCode] House Robber
- 2015出现神曲空挡期,玖月奇迹接棒筷子兄弟?
- Android批量打包教程
- AndroidStudio问题解决系列1—ADB无响应
- hdu1213 How Many Tables
- AC 自动机