Codechef July Challenge 2018 : Subway Ride
首先(想了很久之后)注意到一个性质:同一条边有多种颜色的话保留3种就可以了,这是因为假如最优解要求当前位置与相邻两条边都不相同,那么只要有3条边,就肯定可以满足这一点。
完事就做一个nlogn*3^4的倍增dp就行了……实际肯定是跑不满的(而且cc机子快)。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MN 510000
using namespace std; int n,m,l[MN],F[MN][],_F[MN][],v[MN][][][],num=,x,y,w,C[MN][],de[MN];
struct na{
int y,w,ne;
}b[MN<<];
inline void add(int x,int y,int w){b[++num].y=y;b[num].w=w;b[num].ne=l[x];l[x]=num;}
void dfs(int x,int f){
if (F[x][]) return;
F[x][]=x;F[x][]=f;
for (int i=;i<;i++)
if (!(F[x][i]=F[F[F[x][i-]][i-]][])) break;
_F[x][]=f;
for (int i=;i<;i++)
if (!(_F[x][i]=_F[_F[x][i-]][i-])) break; for (int i=l[x];i;i=b[i].ne)
if (b[i].y!=f){
dfs(b[i].y,x);
if (!C[b[i].y][]) C[b[i].y][]=b[i].w;else
if (!C[b[i].y][]) C[b[i].y][]=b[i].w;else
if (!C[b[i].y][]) C[b[i].y][]=b[i].w;
}
}
void DFS(int x,int f){
if (de[x]) return;
de[x]=de[f]+; for (int a=;a<;a++)
for (int b=;b<;b++)
if (a!=b) v[x][][a][b]=-1e8; int tmp1,tmp2,tmp3;
for (int i=;i<;i++)
if (_F[x][i])
for (int a=;a<;a++)
if (C[x][a])
for (int b=;b<;b++)
if (C[F[x][i]][b])
for (int A=;A<;A++)
if (C[F[x][i-]][A])
if ((tmp1=v[x][i-][a][A])>=)
for (int B=;B<;B++)
if (C[_F[x][i-]][B])
if ((tmp2=v[_F[x][i-]][i-][B][b])>=)
if (v[x][i][a][b]<(tmp3=tmp1+tmp2+(C[F[x][i-]][A]!=C[_F[x][i-]][B]))) v[x][i][a][b]=tmp3; for (int i=l[x];i;i=b[i].ne)
if (b[i].y!=x) DFS(b[i].y,x);
}
inline int ask(int x,int y){
if (de[x]>de[y]) swap(x,y);
int ans[][],la[];
memset(ans,,sizeof(ans));
memset(la,,sizeof(la));
for (int i=;i>=;i--)
if (de[_F[y][i]]>=de[x]){
if (la[]==){
for (int a=;a<;a++)
for (int b=;b<;b++)
if (ans[][b]<v[y][i][a][b])
ans[][b]=v[y][i][a][b];
la[]=F[y][i];
y=_F[y][i];
}else{
int tmp[]={,,},TMP;
for (int a=;a<;a++)
if (C[la[]][a])
for (int b=;b<;b++)
if (C[y][b])
for (int c=;c<;c++)
if (C[F[y][i]][c])
if (tmp[c]<(TMP=ans[][a]+v[y][i][b][c]+(C[la[]][a]!=C[y][b]))) tmp[c]=TMP;
for (int a=;a<;a++) ans[][a]=tmp[a]; la[]=F[y][i];
y=_F[y][i];
}
}
if (x==y){
int tmp=;
for (int a=;a<;a++) if (ans[][a]>tmp) tmp=ans[][a];
return tmp;
}
int st[]={x,y};
for (int i=;i>=;i--)
if (_F[st[]][i]!=_F[st[]][i]){
for (int j=;j<;j++){
if (la[j]==){
for (int a=;a<;a++)
for (int b=;b<;b++)
if (ans[j][b]<v[st[j]][i][a][b])
ans[j][b]=v[st[j]][i][a][b];
la[j]=F[st[j]][i];
st[j]=_F[st[j]][i];
}else{
int tmp[]={-,-,-},TMP;
for (int a=;a<;a++)
if (C[la[j]][a])
for (int b=;b<;b++)
if (C[st[j]][b])
for (int c=;c<;c++)
if (C[F[st[j]][i]][c])
if (tmp[c]<(TMP=ans[j][a]+v[st[j]][i][b][c]+(C[la[j]][a]!=C[st[j]][b]))) tmp[c]=TMP;
for (int a=;a<;a++) ans[j][a]=tmp[a]; la[j]=F[st[j]][i];
st[j]=_F[st[j]][i];
}
}
}
int i=;
for (int j=;j<;j++){
if (la[j]==){
for (int a=;a<;a++)
for (int b=;b<;b++)
if (ans[j][b]<v[st[j]][i][a][b])
ans[j][b]=v[st[j]][i][a][b];
la[j]=F[st[j]][i];
st[j]=_F[st[j]][i];
}else{
int tmp[]={-,-,-},TMP;
for (int a=;a<;a++)
if (C[la[j]][a])
for (int b=;b<;b++)
if (C[st[j]][b])
for (int c=;c<;c++)
if (C[F[st[j]][i]][c])
if (tmp[c]<(TMP=ans[j][a]+v[st[j]][i][b][c]+(C[la[j]][a]!=C[st[j]][b]))) tmp[c]=TMP;
for (int a=;a<;a++) ans[j][a]=tmp[a]; la[j]=F[st[j]][i];
st[j]=_F[st[j]][i];
}
}
int tmp=;
for (int a=;a<;a++)
for (int b=;b<;b++)
if (tmp<ans[][a]+ans[][b]+(C[la[]][a]!=C[la[]][b])) tmp=ans[][a]+ans[][b]+(C[la[]][a]!=C[la[]][b]);
return tmp;
}
int main(){
scanf("%d%d",&n,&m);
for (int i=;i<=m;i++){
scanf("%d%d%d",&x,&y,&w);
add(x,y,w);add(y,x,w);
}
dfs(,);DFS(,);
//printf(">_<%d %d %d\n",C[3][0],C[3][1],C[3][2]);
/*for (int i=1;i<=n;i++,puts("")){
printf("%d:",i);
for (int j=0;j<3;j++) printf("%d ",C[i][j]);
}*/
//printf("%d %d\n",v[6][2][0][0],_F[6][2]);
scanf("%d",&m);
while(m--){
scanf("%d%d",&x,&y);
printf("%d\n",ask(x,y));
}
}
Codechef July Challenge 2018 : Subway Ride的更多相关文章
- Codechef July Challenge 2018 : Picking Fruit for Chefs
传送门 好久没写题解了,就过来水两篇. 对于每一个人,考虑一个序列$A$,$A_I$表示当k取值为 i 时的答案. 如果说有两个人,我们可以把$(A+B)^k$二项式展开,这样就发现把两个人合并起来的 ...
- Codechef October Challenge 2018 游记
Codechef October Challenge 2018 游记 CHSERVE - Chef and Serves 题目大意: 乒乓球比赛中,双方每累计得两分就会交换一次发球权. 不过,大厨和小 ...
- Codechef September Challenge 2018 游记
Codechef September Challenge 2018 游记 Magician versus Chef 题目大意: 有一排\(n(n\le10^5)\)个格子,一开始硬币在第\(x\)个格 ...
- codechef February Challenge 2018 简要题解
比赛链接:https://www.codechef.com/FEB18,题面和提交记录是公开的,这里就不再贴了 Chef And His Characters 模拟题 Chef And The Pat ...
- Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal
原文链接http://www.cnblogs.com/zhouzhendong/p/9010945.html 题目传送门 - Codechef STMINCUT 题意 在一个有边权的无向图中,我们定义 ...
- Codechef August Challenge 2018 : Chef at the River
传送门 (要是没有tjm(Sakits)的帮忙,我还真不知道啥时候能做出来 结论是第一次带走尽可能少的动物,使未带走的动物不冲突,带走的这个数量就是最优解. 首先这个数量肯定是下界,更少的话连第一次都 ...
- Codechef August Challenge 2018 : Safe Partition
传送门 (虽然是A了但是不知道复杂度是不是正确的 考虑以某个位置为结尾的合法划分 先考虑min,带来的影响是限制了最小长度,预处理出这个最小长度后,这可以在处理到这个数时,把不能算的部分去掉(不满足m ...
- Codechef August Challenge 2018 : Interactive Matrix
传送门 首先整个矩阵可以被分为很多小矩阵,小矩阵内所有行的单调性是一样的,所有列的单调性是一样的. 考虑如何在这样一个小矩阵中找出答案.我的策略是每次取四个角中最大值和最小值的点,这样可以每次删掉一行 ...
- Codechef August Challenge 2018 : Lonely Cycles
传送门 几波树形dp就行了. #include<cstdio> #include<cstring> #include<algorithm> #define MN 5 ...
随机推荐
- Docker:私有仓库registry [十一]
一.运行docker私有仓库 安装registry docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregi ...
- VUE-Windows系统下搭建vue环境
一.安装node.js(https://nodejs.org/en/) 下载完毕后,可以安装node,建议不要安装在系统盘(如C:).注意记下路径.. 此处默认安装这4项即可,点击Next按钮. ...
- CSS难点 为什么height设置100%会失效,分栏目等高布局(高度自适用布局)的实现方案
前言 相信在平时写CSS的时候大家都或多或少遇见过设置了height为百分比的时候发现不起作用.今天我们就来一探究竟 原因:父元素未设置具体高度,子元素设置height:100%是无效的. 现象以及方 ...
- IScroll某些手机下不触发ScrollEnd问题处理
同样是微信7.0,看起来内核都是x5内核,两款不同的手机,一个有问题,一个没有问题. IScroll在问题手机下会出现快速拨动时候不触发ScrollEnd事件现象,轻点一次才会触发,解决办法 docu ...
- Groovy 设计模式 -- 迭代器模式
Iterator Pattern http://groovy-lang.org/design-patterns.html#_flyweight_pattern 迭代器模式,允许顺序访问 聚集对象中的中 ...
- DIV浮动层被OCX控件遮蔽解决方案
在开发中需要在网页中嵌入OCX控件,但是控件嵌入后,总是会出现在网页最顶层,页面中的浮动DIV总是不能正常显示,会被遮蔽掉,那么这里就需要特殊处理一下: OBJECT会遮蔽掉页面内容,但是IFRAME ...
- day 15 - 2 内置函数练习
内置函数练习 编写 sql 查询语句功能 文件内容: 1,Eva,22,13651054608,IT2,Vera,23,13304320533,Tearcher3,Renault,25,1333235 ...
- Codeforces 544E K Balanced Teams (DP)
题目: You are a coach at your local university. There are nn students under your supervision, the prog ...
- 数位dp 的简单入门
时间紧张,就不讲那么详细了. 之前一直被深搜代码误解,以为数位dp 其实就是记忆化深搜...(虽说爆搜确实很舒服而且还好想) 但是后来发现数位dp 的标准格式其实是 预处理 + dp ...... 数 ...
- Java_变量类型
目录 主要是为了复习java相关知识,本文主要内容来自于 http://www.runoob.com/java 一.局部变量 局部变量声明在方法.构造方法或语句块中 在方法.构造方法.语句块被执行的时 ...