缩点
来源:互联网 发布:啤酒配方软件中文版 编辑:程序博客网 时间:2024/04/30 05:26
luogu P3387
一开始蠢蠢地用并查集判断两个强连通分量是否连通,防止重复建边,调了一个晚上才发现有向图不能用并查集判断,如果 a -> b <- c
,a 和 c 是不连通的。其实边重复建了也没有影响。
tarjan + 拓扑排序
#include<cstdio>#include<algorithm>using namespace std;const int N = 10005;struct edge{ int from,to,next;}e[10*N];struct edge2{ int to,next;}g[10*N];int head[N],dfn[N],low[N],dfs_clock,color[N],col_num;int sta[N],top,indgr[N],w[N],vi[N],p[N],head2[N],tot,ans;bool isin[N];void tarjan(int u){ dfn[u]=low[u]=++dfs_clock; sta[++top]=u; isin[u]=true; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(isin[v]) { low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]) { isin[u]=false; color[u]=++col_num; w[col_num]=vi[u]; while(sta[top]!=u) { int v=sta[top]; w[col_num]+=vi[v]; isin[v]=false; color[v]=col_num; --top; } --top; }}void Add(int from,int to){ g[++tot].next=head2[from]; g[tot].to = to; head2[from] = tot;}void dp(int u){ p[u]=w[u]; for(int i=head2[u];i;i=g[i].next) { int v=g[i].to; if(!p[v]) dp(v); p[u]=max(p[u],p[v]+w[u]); }}int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { scanf("%d",&vi[i]); } for(int i=1;i<=m;++i) { int u,v; scanf("%d%d",&u,&v); e[i].next = head[u]; e[i].from = u; e[i].to = v; head[u] = i; } for(int i=1;i<=n;++i) { if(!dfn[i]) { dfs_clock=0; tarjan(i); } } for(int i=1;i<=m;++i) { int u=e[i].from,v=e[i].to; if(color[u]!=color[v]) { Add(color[u],color[v]); ++indgr[color[v]]; } } top=0; for(int i=1;i<=col_num;++i) { if(indgr[i]==0) { sta[++top]=i; p[i]=w[i]; } } while(top) { int u=sta[top--]; for(int i=head2[u];i;i=g[i].next) { int v=g[i].to; p[v]=max(p[v],p[u]+w[v]); if(--indgr[v]==0) sta[++top]=v; } } for(int i=1;i<=col_num;++i) ans=max(ans,p[i]); printf("%d\n",ans); return 0;}
tarjan + dfs
#include<cstdio>#include<algorithm>using namespace std;const int N = 10005;struct edge{ int from,to,next;}e[10*N];struct edge2{ int to,next;}g[10*N];int head[N],dfn[N],low[N],dfs_clock,color[N],col_num;int sta[N],top,indgr[N],w[N],vi[N],p[N],head2[N],tot,ans;bool isin[N];void tarjan(int u){ dfn[u]=low[u]=++dfs_clock; sta[++top]=u; isin[u]=true; for(int i=head[u];i;i=e[i].next) { int v=e[i].to; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(isin[v]) { low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]) { isin[u]=false; color[u]=++col_num; w[col_num]=vi[u]; while(sta[top]!=u) { int v=sta[top]; w[col_num]+=vi[v]; isin[v]=false; color[v]=col_num; --top; } --top; }}void Add(int from,int to){ g[++tot].next=head2[from]; g[tot].to = to; head2[from] = tot;}void dp(int u){ p[u]=w[u]; for(int i=head2[u];i;i=g[i].next) { int v=g[i].to; if(!p[v]) dp(v); p[u]=max(p[u],p[v]+w[u]); }}int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { scanf("%d",&vi[i]); } for(int i=1;i<=m;++i) { int u,v; scanf("%d%d",&u,&v); e[i].next = head[u]; e[i].from = u; e[i].to = v; head[u] = i; } for(int i=1;i<=n;++i) { if(!dfn[i]) { dfs_clock=0; tarjan(i); } } for(int i=1;i<=m;++i) { int u=e[i].from,v=e[i].to; if(color[u]!=color[v]) { Add(color[u],color[v]); } } for(int i=1;i<=col_num;++i) { if(!p[i]) { dp(i); } ans=max(ans,p[i]); } printf("%d\n",ans); return 0;}
阅读全文
2 0
- 缩点
- 缩点
- 缩点
- 缩点
- 缩点
- kosaraju+缩点
- 关于缩点
- 关于缩点
- poj1904 tarjan缩点
- HDU3836 Tarjan缩点
- 关于缩点
- HDU3836(tarjan+缩点)
- 1827 tarjan+缩点
- tarjan+缩点
- tarjan + 缩点
- Tarjan缩点
- uvaLive_4287_Proving Equivalences(缩点)
- POJ1236----tarjan缩点
- 用实例域代替序数。
- 两张不同表结构的翻页
- 我的第一个Linux小程序----进度条
- 随机访问流和合并流
- 单例模式与全局唯一id的思考----c++ ,c ,python 实现
- 缩点
- 最新的Fresco加载Gif图片
- 京东商城评论爬虫
- ffmpeg输出yuv的函数堆栈(h264)
- LOJ6253:「CodePlus 2017 11 月赛」Yazid 的新生舞会 (线段树)
- 最小长度电路板排列问题(回溯)
- An End-to-End Approach to Natural Language Object Retrieval via Context-Aware Deep Reinforcement Lea
- 回溯法
- 《TCP/IP详解 卷1》 笔记: TCP连接的建立与终止