bzoj千题计划232:bzoj4727: [POI2017]Turysta
2018-02-11 11:43
267 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=4727
竞赛图tarjan缩点后得到的拓扑图一定是一条链
因为竞赛图任意两点的前后顺序确定,只有一种拓扑序列
竞赛图tarjan缩完点后,若出现强联通分量A和B
那么A中所有点 和 B中所有点的连边 要么全指向A中所有点,要么全指向B中所有点
否则A和B就是一个强联通分量
所以把缩完点之后按点的入度从小到大排序,即可得到竞赛图的拓扑序列
在这个拓扑序列上,可以从前面的强联通分量中任意一个点出来,到达后面的强联通分量的任意一个点
因为竞赛图的任意强联通子图存在一条哈密顿回路
那么再求出每个强联通分量的哈密顿回路
枚举起点,先把起点所在的哈密顿回路扔进栈,然后再按拓扑序把后面的哈密顿回路扔进栈,输出即可
如何在竞赛图哈密顿路径的基础上构造回路,详请参见博客http://www.cnblogs.com/TheRoadToTheGold/p/8439160.html
竞赛图tarjan缩点后得到的拓扑图一定是一条链
因为竞赛图任意两点的前后顺序确定,只有一种拓扑序列
竞赛图tarjan缩完点后,若出现强联通分量A和B
那么A中所有点 和 B中所有点的连边 要么全指向A中所有点,要么全指向B中所有点
否则A和B就是一个强联通分量
所以把缩完点之后按点的入度从小到大排序,即可得到竞赛图的拓扑序列
在这个拓扑序列上,可以从前面的强联通分量中任意一个点出来,到达后面的强联通分量的任意一个点
因为竞赛图的任意强联通子图存在一条哈密顿回路
那么再求出每个强联通分量的哈密顿回路
枚举起点,先把起点所在的哈密顿回路扔进栈,然后再按拓扑序把后面的哈密顿回路扔进栈,输出即可
如何在竞赛图哈密顿路径的基础上构造回路,详请参见博客http://www.cnblogs.com/TheRoadToTheGold/p/8439160.html
#include<cstdio> #include<vector> #include<iostream> #include<algorithm> using namespace std; #define N 2001 int n; bool mp ; int tot; int dfn ,low ; int st ,top; bool vis ; int cnt; int id ; vector<int>scc ; int nxt ; int pos ,in ; template<typename T> void read(T &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } void tarjan(int x) { dfn[x]=low[x]=++tot; st[++top]=x; vis[x]=true; for(int i=1;i<=n;++i) { if(!mp[x][i]) continue; if(!dfn[i]) { tarjan(i); low[x]=min(low[x],low[i]); } else if(vis[i]) low[x]=min(low[x],dfn[i]); } if(low[x]==dfn[x]) { cnt++; while(st[top]!=x) { scc[cnt].push_back(st[top]); id[st[top]]=cnt; vis[st[top--]]=false; } scc[cnt].push_back(x); id[x]=cnt; vis[x]=false; top--; } } bool cmp(int a,int b) { return in[a]<in[b]; } void insert(int x) { st[++top]=x; for(int i=nxt[x];i && i!=x;i=nxt[i]) st[++top]=i; } int main() { read(n); for(int i=1;i<n;++i) for(int j=1;j<=i;++j) { read(mp[j][i+1]); mp[i+1][j]=mp[j][i+1]^1; } for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i); for(int now=1;now<=cnt;++now) { int siz=scc[now].size(); int l,r; l=r=scc[now][0]; for(int i=1,t;i<siz;++i) { t=scc[now][i]; if(mp[t][l]) nxt[t]=l,l=t; else if(mp[r][t]) nxt[r]=t,r=t; else { for(int j=l;j;j=nxt[j]) if(mp[j][t] &&mp[t][nxt[j]]) { nxt[t]=nxt[j]; nxt[j]=t; break; } } } r=0; for(int i=nxt[l];i;i=nxt[i]) if(r) { for(int j=r,k=l;;k=j,j=nxt[j]) { if(mp[i][j]) { nxt[k]=nxt[l]; if(k!=l) nxt[l]=r; l=i; r=j; break; } if(j==l) break; } } else if(mp[i][l]) r=l,l=i; nxt[l]=r; } for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(id[i]!=id[j] && mp[i][j]) in[id[j]]++; for(int i=1;i<=cnt;++i) { pos[i]=i; in[i]/=scc[i].size(); } sort(pos+1,pos+cnt+1,cmp); for(int i=1;i<=n;++i) { top=0; insert(i); for(int j=1,t;j<=cnt;++j) if(in[t=pos[j]]>in[id[i]]) insert(scc[t][0]); printf("%d ",top); for(int j=1;j<=top;++j) { printf("%d",st[j]); putchar(j==top ? '\n' : ' '); } } }
相关文章推荐
- BZOJ4727: [POI2017]Turysta
- BZOJ4727 [POI2017]Turysta 【竞赛图哈密顿路径/回路】
- BZOJ 4727: [POI2017]Turysta
- 【BZOJ4727】【POI2017】Turysta
- bzoj 4727 [POI2017]Turysta 竞赛图
- bzoj4727 [POI2017]Turysta(竞赛图构造哈密顿回路)
- BZOJ4727 [POI2017]Turysta
- bzoj 4727: [POI2017]Turysta 图论
- BZOJ4727: [POI2017]Turysta
- bzoj千题计划151:bzoj1131: [POI2008]Sta
- BZOJ4727: [POI2017]Turysta tarjan/竞赛图哈密顿
- BZOJ.4727.[POI2017]Turysta(哈密顿路径/回路 竞赛图)
- 4727: [POI2017]Turysta
- bzoj千题计划272:bzoj4557: [JLoi2016]侦察守卫
- BZOJ2132: 圈地计划
- 【APIO2009】BZOJ1179 BSOJ2468 CODEVS1611 抢掠计划
- bzoj1613 [Usaco2007 Jan]Running贝茜的晨练计划
- [BZOJ]4726 [POI2017] Sabota? 树形Dp
- 【BZOJ4725】【POI2017】Reprezentacje ró?nicowe
- 【codevs4632】【BZOJ4326】运输计划,链剖+二分+差分