传送门

首先(想了很久之后)注意到一个性质:同一条边有多种颜色的话保留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的更多相关文章

  1. Codechef July Challenge 2018 : Picking Fruit for Chefs

    传送门 好久没写题解了,就过来水两篇. 对于每一个人,考虑一个序列$A$,$A_I$表示当k取值为 i 时的答案. 如果说有两个人,我们可以把$(A+B)^k$二项式展开,这样就发现把两个人合并起来的 ...

  2. Codechef October Challenge 2018 游记

    Codechef October Challenge 2018 游记 CHSERVE - Chef and Serves 题目大意: 乒乓球比赛中,双方每累计得两分就会交换一次发球权. 不过,大厨和小 ...

  3. Codechef September Challenge 2018 游记

    Codechef September Challenge 2018 游记 Magician versus Chef 题目大意: 有一排\(n(n\le10^5)\)个格子,一开始硬币在第\(x\)个格 ...

  4. codechef February Challenge 2018 简要题解

    比赛链接:https://www.codechef.com/FEB18,题面和提交记录是公开的,这里就不再贴了 Chef And His Characters 模拟题 Chef And The Pat ...

  5. Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal

    原文链接http://www.cnblogs.com/zhouzhendong/p/9010945.html 题目传送门 - Codechef STMINCUT 题意 在一个有边权的无向图中,我们定义 ...

  6. Codechef August Challenge 2018 : Chef at the River

    传送门 (要是没有tjm(Sakits)的帮忙,我还真不知道啥时候能做出来 结论是第一次带走尽可能少的动物,使未带走的动物不冲突,带走的这个数量就是最优解. 首先这个数量肯定是下界,更少的话连第一次都 ...

  7. Codechef August Challenge 2018 : Safe Partition

    传送门 (虽然是A了但是不知道复杂度是不是正确的 考虑以某个位置为结尾的合法划分 先考虑min,带来的影响是限制了最小长度,预处理出这个最小长度后,这可以在处理到这个数时,把不能算的部分去掉(不满足m ...

  8. Codechef August Challenge 2018 : Interactive Matrix

    传送门 首先整个矩阵可以被分为很多小矩阵,小矩阵内所有行的单调性是一样的,所有列的单调性是一样的. 考虑如何在这样一个小矩阵中找出答案.我的策略是每次取四个角中最大值和最小值的点,这样可以每次删掉一行 ...

  9. Codechef August Challenge 2018 : Lonely Cycles

    传送门 几波树形dp就行了. #include<cstdio> #include<cstring> #include<algorithm> #define MN 5 ...

随机推荐

  1. CMDB服务器管理系统【s5day88】:采集资产之Agent、SSH和Salt模式讲解

    在对获取资产信息时,简述有四种方案. 1.Agent  (基于shell命令实现) 原理图 Agent方式,可以将服务器上面的Agent程序作定时任务,定时将资产信息提交到指定API录入数据库 优点: ...

  2. Docker:跨主机容器间通信之overlay [十五]

    一.配置overlay类型网络准备工作 1.在luoahong3主机上 docker run -d -p 8500:8500 -h consul --name consul progrium/cons ...

  3. oh-my-zsh安装和简单定制

    我使用的是deepin系统,deepin的终端做的已经很好了,最近想换一个新的命令的提示符风格.据说oh-my-zsh很好用,花一点时间安装,记录这个过程. oh-my-zsh的安装是非常方便的,安装 ...

  4. Python系列之 - 前端总结

    1. python序列化: 字符串 = json.dumps(对象) 对象->字符串 对象 = json.loads(字符串) 字符串->对象 Javascript: 字符串 = JSON ...

  5. django - 总结 - admin

    admin组件,一旦我们注册了表以后,会自动生成很多url,那他是如何添加的呢, 因为admin在启动后会自动执行每个app下的ready方法: 具体是由 from django.utils.modu ...

  6. Aurora — 一个在 MSOffice 内输入 LaTeX 公式的很好用插件

    from http://blog.csdn.net/GarfieldEr007/article/details/51452986 工具名称:Aurora2x  (下载) 压缩包内有详细的安装说明. 刚 ...

  7. Factorized TDNN(因子分解TDNN,TDNN-F)

    论文 Povey, D., Cheng, G., Wang, Y., Li, K., Xu, H., Yarmohamadi, M., & Khudanpur, S. (2018). Semi ...

  8. 请求超时VUE axios重新再次请求

    //在main.js设置全局的请求次数,请求的间隙 axios.defaults.retry = 4; axios.defaults.retryDelay = 1000; axios.intercep ...

  9. 记事本:CSS

    css更多的是一种用来修饰HTML的语言 CSS的三种引入方式 1.行内样式:一般不会这样写,如果想选择某一个,可以用之后内部样式中更加详细的选中方式 行内的优先级最高 <p style=&qu ...

  10. 【原创】大数据基础之Drill(2)Drill1.14+Hive2.1.1运行

    问题 Drill最新版本是1.14,从1.13开始Drill支持hive的版本升级到2.3.2,详见1.13的release notes The Hive client for Drill is up ...