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\) 的倍数,那么有 \ ...
随机推荐
- vue class与style 绑定详解——小白速会
一.绑定class的几种方式 1.对象语法 直接看例子: <div id="app3"> <div :class="{'success':isSucce ...
- jupyter notebook下python2和python3共存(Ubuntu)
提示NOTICE 时间:2018/04/06 主题:Ubuntu 下CAFFE框架 主角:Jupyter Notebook 简介: Jupyter Notebook(此前被称为 IPython not ...
- 详解k8s一个完整的监控方案(Heapster+Grafana+InfluxDB) - kubernetes
1.浅析整个监控流程 heapster以k8s内置的cAdvisor作为数据源收集集群信息,并汇总出有价值的性能数据(Metrics):cpu.内存.网络流量等,然后将这些数据输出到外部存储,如Inf ...
- jq 滚轮监听事件
windowAddMouseWheel(); function windowAddMouseWheel() { var i = 0; var scrollFunc = function (e) { e ...
- Linux进程管理:查杀进程
一.查看进程 Linux下显示系统进程的命令ps,最常用的有ps -ef 和ps aux.这两个到底有什么区别呢? 两者没太大差别,讨论这个问题,要追溯到Unix系统中的两种风格,System V风格 ...
- Oracle复合B*tree索引branch block内是否包含非先导列键值?
好久不碰数据库底层细节的东西,前几天,一个小家伙跑来找我,非要说复合b*tree index branch block中只包含先导列键值信息,并不包含非先导列键值信息,而且还dump了branch b ...
- shiro中CacheManager相关的类结构介绍,提供redis Cache实现
cacheManager主要用于对shiro中的session.realm中的认证信息.授权信息进行缓存. 1.类结构 2.接口及类介绍 CacheManager 提供根据名字获取cache的作用. ...
- mysql中出现Unknown column 'qwe' in 'field list'的错误
下面是我建表的代码 输入数据的代码 可以看到出现了类似Unknown column 'qwe' in 'field list'的错误 当时看了好久改了又改都没有找到错误,直道我在一次打C语言代码的过程 ...
- 微信小程序:模板消息推送提示{“errcode”:41030,”errmsg”:”invalid page hint: [gP1eXXXXXX]”}
在开发小程序 模板消息定时推送功能时,在开发版测试程序功能运行正常,但提交到线上后提示报错{“errcode”:41030,”errmsg”:”invalid page hint: [gP1eXXXX ...
- 使用poi导出数据到excel
一.首先是导入poi所需要的jar包,我是用的是maven,添加jar包依赖 <dependency> <groupId>org.apache.poi</groupId& ...