4727: [POI2017]Turysta

Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special Judge
Submit: 117  Solved: 39
[Submit][Status][Discuss]

Description

给出一个n个点的有向图,任意两个点之间有且仅一条有向边。对于每个点v,求出从v出发的一条经过点数最多,
且没有重复经过同一个点两次以上的简单路径。

Input

第一行包含一个正整数n(2<=n<=2000),表示点数。接下来n-1行,其中的第i行有i-1个数,如果第j个数是1,那么
表示有向边j->i+1,如果是0,那么表示有向边j<-i+1。

Output

输出n行,第i行首先包含一个正整数k,表示从i点出发的最优路径所经过的点数,接下来k个正整数,依次表示路
径上的每个点。若有多组最优解,输出任意一组。

Sample Input

4
1
1 1
1 0 1

Sample Output

4 1 2 3 4
3 2 3 4
3 3 4 2
3 4 2 3

HINT

Source

鸣谢Claris上传

分析:

这是一张有向完全图也就是竞赛图...

No.1 竞赛图一定存在一条哈密顿路径

我们可以构法证明,详细证明请移步这里

No.2 强联通的竞赛图一定存在一条哈密顿回路

依旧是构造法证明,构造方法如下:

首先,我们求出这个强联通分量的哈密顿路径,然后把路径变成环,然后考虑扩大环的大小...

把路径变成环就不用说了,一定存在一个环...

然后考虑下面的几种情况:

6代表的是链上离环最近的点

1、存在一条6->1的路径,直接连上就好(这个和第二种情况的区别就是5这个点是环和链的连接点,第二种情况是环上任意点,本质上是一样的,但是代码实现有一些区别...)

2、存在一条x->6->nxt[x]的路径

3、6不指向环上任何一个点,这时候一定存在链上其他的点指向环上(因为这个图是强联通的),比如说存在一条7->2的路径,那么新的环就是1->6->7->2->3->4->5->1

这样我们就构造除了一个强联通竞赛图的哈密顿回路...

我们把给出的竞赛图缩点,每个点是一个强联通分量,这就变成了一张DAG,每个强联通分量中找出一个哈密顿回路,那么发现不管从哪个点进入强联通分量都可以遍历这个环然后到达这个强联通分量指向的下一个强联通分量,因为这个强联通分量里的每个点都存在指向下一个强联通分量的边,否则这个和下一个就强联通了...

所以我们DP计算出从这个点出发所能找到的最长的路径...

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std; const int maxn=2000+5; int n,tail,G[maxn][maxn],M[maxn][maxn],ans[maxn],que[maxn],siz[maxn],node[maxn],can[maxn];
int C,tim,top,mp[maxn],dfn[maxn],low[maxn],stk[maxn],vis[maxn],instk[maxn],f[maxn],nt[maxn],nxt[maxn]; inline void push(int x){
vis[x]=1;
for(int i=1;i<=tail;i++)
if(G[que[i]][x])
can[que[i]]=1;
} inline void find(void){
int l=que[1],r=que[1];
for(int i=2;i<=tail;i++){
int x=que[i];
if(G[x][l])
nxt[x]=l,l=x;
else{
for(int now=l,last=0;;last=now,now=nxt[now]){
if(last==r){
nxt[r]=x;r=x;
break;
}
else if(G[x][now]){
nxt[last]=x;
nxt[x]=now;
break;
}
}
}
}
int d=l;push(l);
while(d!=r){
int x=nxt[d];
if(G[x][l])
d=x,push(x);
else{
for(int now=l,last=0;;last=now,now=nxt[now]){
if(G[x][now]){
nxt[last]=x;
nxt[d]=l;
d=x;l=now;
push(x);
break;
}
else if(last==d){
int nownode,t;
for(int i=1;i<=tail;i++)
if(!vis[que[i]]&&can[que[i]]){
nownode=que[i];
break;
}
for(int i=l;;i=nxt[i])
if(G[nownode][i]||i==d){
t=i;
break;
}
for(int i=nxt[d];;i=nxt[i]){
push(i);
if(i==nownode)
break;
}
nxt[d]=l,l=t,d=nownode;
for(int now=l;;now=nxt[now])
if(nxt[now]==t){
nxt[now]=x;
break;
}
break;
}
}
}
}
nxt[r]=l;
for(int i=1;i<=tail;i++)
vis[que[i]]=can[que[i]]=0;
} inline void tarjan(int root){
dfn[root]=low[root]=++tim,stk[++top]=root,instk[root]=1;
for(int i=1;i<=n;i++)
if(G[root][i]){
if(!dfn[i])
tarjan(i),low[root]=min(low[root],low[i]);
else if(instk[i])
low[root]=min(low[root],dfn[i]);
}
if(dfn[root]==low[root]){
C++;node[C]=root;tail=0;int tmp;
do{
tmp=stk[top--];instk[tmp]=0;mp[tmp]=C;siz[C]++;que[++tail]=tmp;
}while(tmp!=root);
find();
}
} inline int dp(int x){
if(f[x])
return f[x];
for(int i=1,tmp;i<=C;i++)
if(i!=x&&M[x][i]){
tmp=dp(i);
if(f[x]<tmp)
f[x]=tmp,nt[x]=i;
}
f[x]+=siz[x];
return f[x];
} inline void print(int x){
if(x){
printf(" %d",x);
for(int i=nxt[x];i!=x;i=nxt[i])
printf(" %d",i);
print(node[nt[mp[x]]]);
}
} signed main(void){
scanf("%d",&n);
for(int j=2;j<=n;j++)
for(int i=1;i<j;i++)
scanf("%d",&G[i][j]),G[j][i]=G[i][j]^1;
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(G[i][j]&&mp[i]!=mp[j])
M[mp[i]][mp[j]]=1;
for(int i=1;i<=C;i++)
dp(i);
for(int i=1;i<=n;i++)
printf("%d",f[mp[i]]),print(i),puts("");
return 0;
}

  


By NeighThorn

BZOJ 4727: [POI2017]Turysta的更多相关文章

  1. BZOJ.4727.[POI2017]Turysta(哈密顿路径/回路 竞赛图)

    题目链接 \(Description\) 给出一个n个点的有向图,任意两个点之间有且仅一条有向边.对于每个点v,求出从v出发的一条经过点数最多,且没有重复经过同一个点一次以上的简单路径. n<= ...

  2. bzoj千题计划232:bzoj4727: [POI2017]Turysta

    http://www.lydsy.com/JudgeOnline/problem.php?id=4727 竞赛图tarjan缩点后得到的拓扑图一定是一条链 因为竞赛图任意两点的前后顺序确定,只有一种拓 ...

  3. BZOJ 4726: [POI2017]Sabota?

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 301  Solved ...

  4. BZOJ 4726: [POI2017]Sabota? 树形dp

    4726: [POI2017]Sabota? 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4726 Description 某个公司有n ...

  5. bzoj 4725 [POI2017]Reprezentacje ró?nicowe 暴力

    [POI2017]Reprezentacje ró?nicowe Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 141  Solved: 67[Sub ...

  6. bzoj 4724 [POI2017]Podzielno 二分+模拟

    [POI2017]Podzielno Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 364  Solved: 160[Submit][Status][ ...

  7. bzoj 4723 [POI2017]Flappy Bird 模拟

    [POI2017]Flappy Bird Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 482  Solved: 196[Submit][Status ...

  8. BZOJ 4725: [POI2017]Reprezentacje ró?nicowe

    Description 一个数列. \(a_1=1,a_2=2\) 当 \(n>2\) 时 \[a_n = \{  \begin {matrix} 2a_{n-1},\text{n is an ...

  9. BZOJ 4724: [POI2017]Podzielno

    Description 由\([0,B-1]\)的数字构造一个 \(B\) 进制数字,使得他是 \(B-1\) 的倍数. Sol 贪心+二分. 首先 \(X\) 是 \(B-1\) 的倍数,那么有 \ ...

随机推荐

  1. 【iOS】字号问题

    一,ps和pt转换 px:相对长度单位.像素(Pixel).(PS字体) pt:绝对长度单位.点(Point).(iOS字体) 公式如下: pt=(px/96)*72. 二,字体间转换 1in = 2 ...

  2. 【iOS】swift-Binary operator '|' cannot be applied to two UIViewAutoresizing operands

    let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 568)) addSubview(view) view.autoresi ...

  3. phalcon环境的搭建和dll扩展下载与选择

    phalcon需要下载一个扩展的dll文件才能运行项目 其中需要注意dll放在一个php扩展目录中windows下php/ext/,还需要在两个Php.ini文件中增加扩展说明,一般只需要更改 D:\ ...

  4. java中final 关键字的作用

    final 关键字的作用 java中的final关键字可以用来声明成员变量.本地变量.类.方法,并且经常和static一起使用声明常量. final关键字的含义: final在Java中是一个保留的关 ...

  5. tk mybatis通用mapper,复杂and or条件查询

    需求:where查询,需要支持(a or b or c) and d 也就是a.b.c三个条件是或的关系,然后再与d相与. 尝试后,可以通过以下方式处理: 方式1:Weekend语法 Weekend& ...

  6. git初试

    在gitLab上新建一个项目,creat项目文件之后,进入到项目的路径之后,复制命令git clone ‘git@gitlab.touzila.com:xiacaixiang/gitgitTest1. ...

  7. python 类知识点总结

    python 类知识点总结 面向对象思想: 1.设计的时候,一定要明确应用场景 2.由对象分析定义类的时候,找不到共同特征和技能不用强求 1.简述类.对象.实例化.实例这些名词的含义: 类:从一组对象 ...

  8. Struts(二十二):国际化

    如何配置国际化资源文件? 1.Action范围资源文件:在Action类文件所在的路径建立名为ActionName_language_country.properties的文件: 2.包范围资源文件: ...

  9. pandas(七)数据规整化:清理、转换、合并、重塑之合并数据集

    pandas对象中的数据可以通过一些内置的方式进行合并: pandas.merge 可根据一个或多个键将不同的DataFrame中的行连接起来. pandas.concat可以沿着一条轴将多个对象堆叠 ...

  10. 'NoneType' object is not iterable

    "TypeError: 'NoneType' object is not iterable" 一般是返回值为None同时赋值给了多个变量