[BZOJ3887][Usaco2015 Jan]Grass Cownoisseur(tarjan+spfa)
2016-11-04 13:00
555 查看
题目描述
传送门题解
边是可以重复走的,所以在同一个强连通分量里,无论从那个点进入从哪个点出,所有的点一定能被一条路走到。那么首先用tarjan将所有的强连通分量缩成一个点,每个点的权为该强连通分量中点的个数。然后我们考虑将一条边反置。
强连通分量里的边反置是没有价值的,所以只需要考虑DAG里的边。枚举一条要反置的边,如果将这条边反置的话,答案应该为它的起点到1最多能走到的点数和1到它的终点最多能走到的点数,也就是相当于这条边将一个环连通起来了。而从它到1最多能走到的点数和1到它的终点最多能走到的点数可以用两遍spfa最长路预处理好,这个问题就被解决了。
代码
#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; #define N 100005 int n,m,dfs_clock,scc,ans; struct hp{int x,y;}e ; int dfn ,low ,stack ,tmp,belong ,size ,dis ,_dis ; int tot,point ,nxt ,v ; bool vis ; queue <int> q; void add(int x,int y) { ++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y; } void tarjan(int x) { dfn[x]=low[x]=++dfs_clock;vis[x]=true;stack[++tmp]=x; for (int i=point[x];i;i=nxt[i]) if (!dfn[v[i]]) { tarjan(v[i]); low[x]=min(low[x],low[v[i]]); } else if (vis[v[i]]) low[x]=min(low[x],dfn[v[i]]); if (dfn[x]==low[x]) { ++scc;int now=0; while (now!=x) { now=stack[tmp--]; vis[now]=false; belong[now]=scc; size[scc]++; } } } void build() { tot=0;memset(point,0,sizeof(point)); for (int i=1;i<=m;++i) if (belong[e[i].x]!=belong[e[i].y]) add(belong[e[i].x],belong[e[i].y]); } void rebuild() { tot=0;memset(point,0,sizeof(point)); for (int i=1;i<=m;++i) if (belong[e[i].x]!=belong[e[i].y]) add(belong[e[i].y],belong[e[i].x]); } void spfa(int *dis) { memset(vis,0,sizeof(vis)); dis[belong[1]]=size[belong[1]];vis[belong[1]]=true;q.push(belong[1]); while (!q.empty()) { int now=q.front();q.pop(); vis[now]=false; for (int i=point[now];i;i=nxt[i]) if (dis[v[i]]<dis[now]+size[v[i]]) { dis[v[i]]=dis[now]+size[v[i]]; if (!vis[v[i]]) { vis[v[i]]=true; q.push(v[i]); } } } } int main() { scanf("%d%d",&n,&m); for (int i=1;i<=m;++i) { scanf("%d%d",&e[i].x,&e[i].y); add(e[i].x,e[i].y); } for (int i=1;i<=n;++i) if (!dfn[i]) tarjan(i); build(); spfa(dis); rebuild(); spfa(_dis); ans=size[belong[1]]; for (int i=1;i<=m;++i) if (belong[e[i].x]!=belong[e[i].y]) if (_dis[belong[e[i].x]]&&dis[belong[e[i].y]]) ans=max(ans,_dis[belong[e[i].x]]+dis[belong[e[i].y]]-size[belong[1]]); printf("%d\n",ans); }
总结
①一定要好好读题!希望以后不要再有读题方面的失误。相关文章推荐
- [BZOJ3887][Usaco2015 Jan]Grass Cownoisseur(tarjan+spfa)
- bzoj 3887: [Usaco2015 Jan]Grass Cownoisseur(spfa+tarjan)
- 【BZOJ3887】【Usaco2015 Jan】Grass Cownoisseur Tarjan+Spfa
- 【tarjan+拓扑】BZOJ3887-[Usaco2015 Jan]Grass Cownoisseur
- 洛谷—— P3119 [USACO15JAN]草鉴定Grass Cownoisseur || BZOJ——T 3887: [Usaco2015 Jan]Grass Cownoisseur
- BZOJ 【BZOJ3887】【Usaco2015 Jan】Grass Cownoisseur
- 【BZOJ3887】【Usaco2015 Jan】Grass Cownoisseur 算法模块有点多
- BZOJ 3887 [Usaco2015 Jan]Grass Cownoisseur
- bzoj 3887: [Usaco2015 Jan]Grass Cownoisseur
- BZOJ_3887_[Usaco2015 Jan]Grass Cownoisseur_强连通分量+拓扑排序+DP
- [Usaco2015 Jan]Grass Cownoisseur 图论 tarjan spfa
- bzoj 3889: [Usaco2015 Jan]Cow Routing SPFA
- bzoj 3887: Grass Cownoisseur Tarjan+Topusort
- [Usaco2015 Jan]Grass Cownoisseur Tarjan缩点+SPFA
- BZOJ3887: [Usaco2015 Jan]Grass Cownoisseur
- [Usaco2015 Jan]Grass Cownoisseur 图论 tarjan spfa
- BZOJ[3887][Usaco2015 Jan]Grass Cownoisseur Tarjan+拓扑排序
- bzoj3887 [Usaco2015 Jan]Grass Cownoisseur tarjan+拓补排序
- BZOJ 3885 Usaco2015 Jan Cow Rectangles 单调队列+二分
- 【BZOJ】1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会(tarjan)