BZOJ 4727: [POI2017]Turysta
4727: [POI2017]Turysta
Time Limit: 20 Sec Memory Limit: 128 MBSec Special Judge
Submit: 117 Solved: 39
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
1
1 1
1 0 1
Sample Output
3 2 3 4
3 3 4 2
3 4 2 3
HINT
Source
分析:
这是一张有向完全图也就是竞赛图...
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的更多相关文章
- BZOJ.4727.[POI2017]Turysta(哈密顿路径/回路 竞赛图)
题目链接 \(Description\) 给出一个n个点的有向图,任意两个点之间有且仅一条有向边.对于每个点v,求出从v出发的一条经过点数最多,且没有重复经过同一个点一次以上的简单路径. n<= ...
- bzoj千题计划232:bzoj4727: [POI2017]Turysta
http://www.lydsy.com/JudgeOnline/problem.php?id=4727 竞赛图tarjan缩点后得到的拓扑图一定是一条链 因为竞赛图任意两点的前后顺序确定,只有一种拓 ...
- BZOJ 4726: [POI2017]Sabota?
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 301 Solved ...
- BZOJ 4726: [POI2017]Sabota? 树形dp
4726: [POI2017]Sabota? 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4726 Description 某个公司有n ...
- bzoj 4725 [POI2017]Reprezentacje ró?nicowe 暴力
[POI2017]Reprezentacje ró?nicowe Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 141 Solved: 67[Sub ...
- bzoj 4724 [POI2017]Podzielno 二分+模拟
[POI2017]Podzielno Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 364 Solved: 160[Submit][Status][ ...
- bzoj 4723 [POI2017]Flappy Bird 模拟
[POI2017]Flappy Bird Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 482 Solved: 196[Submit][Status ...
- 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 ...
- BZOJ 4724: [POI2017]Podzielno
Description 由\([0,B-1]\)的数字构造一个 \(B\) 进制数字,使得他是 \(B-1\) 的倍数. Sol 贪心+二分. 首先 \(X\) 是 \(B-1\) 的倍数,那么有 \ ...
随机推荐
- iOS 简易无限滚动的图片轮播器-SDCycleScrollView
@interface ViewController () <</span>SDCycleScrollViewDelegate> @end @implementation Vie ...
- servlet线程同步问题-代码实现同步(转)
从servlet的生命周期中,我们知道,当第一次访问某个servlet后,该servlet的实例就会常驻 内存,以后再次访问该servlet就会访问同一个servlet实例,这样就带来多个用户去访问一 ...
- nyoj n-1位数
n-1位数 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的 ...
- excel2003和excel2007文件的创建和读取
excel2003和excel2007文件的创建和读取在项目中用的很多,首先我们要了解excel的常用组件和基本操作步骤. 常用组件如下所示: HSSFWorkbook excel的文档对象 HSSF ...
- Spark性能优化总结
1. 避免重复加载RDD 比如一份从HDFS中加载的数据 val rdd1 = sc.textFile("hdfs://url:port/test.txt"),这个test.txt ...
- vue下拉列表
最近在弄作品,做了个下拉列表.心想各位小哥哥.小姐姐可能会用到相同的需求,就把下拉列表封装一下,希望能对各位小哥哥,小姐姐有帮助 github地址:https://github.com/ClmPisc ...
- JAVA_SE基础——19.数组的定义
数组是一组相关数据的集合,数组按照使用可以分为一维数组.二维数组.多维数组 本章先讲一维数组 不同点: 不使用数组定义100个整形变量:int1,int2,int3;;;;;; 使用数组定义 int ...
- django models的点查询/跨表查询/双下划线查询
django models 在日常的编程中,我们需要建立数据库模型 而往往会用到表与表之间的关系,这就比单表取数据要复杂一些 在多表之间发生关系的情形下,我们如何利用models提供的API的特性获得 ...
- B树和B+树的插入、删除图文详解
简介:本文主要介绍了B树和B+树的插入.删除操作.写这篇博客的目的是发现没有相关博客以举例的方式详细介绍B+树的相关操作,由于自身对某些细节也感到很迷惑,通过查阅相关资料,对B+树的操作有所顿悟,写下 ...
- confluence搭建详情
Confluence安装&破解&汉化 编辑时间: 2017年7月7日18:01:13 1.介绍 Atlassian Confluence(简称Confluence)是一个专业的wiki ...