崆若的水题之--赛跑的乌龟

因为想知道到底哪只乌龟跑的比兔子都快,Kong_Ruo在决定举行一场乌龟赛跑,场地有N座城市,是通过道路相连组成了一个N-1条边的无向无环图。每条边由ai连到bi,距离为ci。Kong_Rup决定选取两个城市分别为起点和终点,举行比赛。比赛时按这两个城市间的最短距离进行比赛。Kong_Ruo想选出一条尽量长的路径,但由于资金限制,路径长最多不能超过k。你能帮帮他吗?

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<ctime>
using namespace std;
const int maxn=30010;
struct Node
{
    Node* ch[2];
    int r,v;
}nodes[maxn],*null=new Node(),*S=null;
queue<Node*> Q;
Node* newnode()
{
    Node* o=Q.front(); Q.pop();
    return o;
}
void del(Node* &o)
{
    Q.push(o); o=null;
}
void rotate(Node* &o,int d)
{
    Node* k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o;
    o=k;
}
void insert(Node* &o,int v)
{
    if(o==null)
    {
        o=newnode();
        o->r=rand();
        o->v=v;
        o->ch[0]=o->ch[1]=null;
    }
    else
    {
        int d=v<o->v?0:1;
        insert(o->ch[d],v);
        if(o->ch[d]->r>o->r) rotate(o,d^1);
    }
}
int find(Node* &o,int v)
{
    if(o==null) return 0;
    int d=v<o->v?0:1;
    if(o->v==v) return v;
    else if(!d) return find(o->ch[0],v);
    else return max(o->v,find(o->ch[1],v));
}
void clean(Node* &o)
{
    if(o==null) return;
    clean(o->ch[0]);clean(o->ch[1]);
    del(o);
}
void print(Node* &o)
{
    if(o==null) return;
    print(o->ch[0]);
    printf("%d ",o->v);
    print(o->ch[1]);
}
int first[maxn],to[maxn*2],next[maxn*2],d[maxn*2];
int n,m=1,k;
void AddEdge(int a,int b,int c)
{
    to[m]=b;
    d[m]=c;
    next[m]=first[a];
    first[a]=m++;
}
int siz,root,f[maxn],s[maxn],done[maxn];
void findroot(int x,int fa)
{
    int maxs=0;
    s[x]=1;
    for(int i=first[x];i;i=next[i]) if(to[i]!=fa&&!done[to[i]])
    {
        findroot(to[i],x);
        s[x]+=s[to[i]];
        maxs=max(maxs,s[to[i]]);
    }
    f[x]=max(siz-s[x],maxs);
    if(f[x]<f[root]) root=x;
}
int ans,A[maxn],tt=0;
void dfs(int x,int fa,int dis)
{
    s[x]=1;
    A[tt++]=dis;
    for(int i=first[x];i;i=next[i])
      if(!done[to[i]]&&to[i]!=fa)
      {
         dfs(to[i],x,dis+d[i]);
         s[x]+=s[to[i]];
      }
}
int tott;
void solve(int x)
{
    done[x]=1;
    insert(S,0);
    for(int i=first[x];i;i=next[i]) if(!done[to[i]])
    {
       tt=0; dfs(to[i],x,d[i]);
       for(int j=0;j<tt&&A[j]<=k;j++) ans=max(ans,find(S,k-A[j])+A[j]);
       for(int j=0;j<tt;j++) insert(S,A[j]);
    }
    clean(S);
    for(int i=first[x];i;i=next[i]) if(!done[to[i]])
    {
       dfs(to[i],x,0);
       siz=f[0]=s[to[i]];
       findroot(to[i],root=0);
       solve(root);
    }
}
int main()
{
    for(int i=0;i<maxn;i++) Q.push(&nodes[i]);
    int a,b,c;
    scanf("%d%d",&n,&k);
    for(int i=1;i<n;i++)
    {
       scanf("%d%d%d",&a,&b,&c);
       AddEdge(a,b,c);
       AddEdge(b,a,c);
    }
    f[0]=siz=n;
    findroot(1,root=0);
    solve(root);
    printf("%d\n",ans);
    return 0;
}

萌萌哒代码~~

输入

第一行为两个正整数N,k,表示N个城市,最长距离为K。
接下来N-1行为ai,bi,ci,表示有一条边从ai到bi,距离为ci。

输出

输出路径在小于等于k的情况下的最长长度。

输入示例

5 7
1 2 3
1 3 4
4 5 7
4 2 2

输出示例

7

时间: 2024-08-29 20:20:36

崆若的水题之--赛跑的乌龟的相关文章

崆若的水题之--全世界最水的邻接表二连发哈哈哈哈

有n个城市,编号为1到n,这些城市当中有m条有向边,现在Kong_Ruo在1号城市,他准备去旅游.如果Kong_Ruo能从城市1到达城市i,并能从城市i回到城市1,那么Kong_Ruo就能去城市i游览.现在请你从小到大输出所有能去游览的城市编号. 输入 第一行:两个整数n,m,分别表示城市个数与有向边个数.后m行:每行两个整数a和b,表示a城市到b城市有一条有向边. 输出 输出所有符合要求的城市编号,每个一行,从小到大输出. 输入示例 5 43 12 34 31 2 输出示例 123 #incl

崆若的水题之--盒子的鬼畜移动

#include<iostream> using namespace std; const int MAXN=100010; int i,m,n,ileft[MAXN],iright[MAXN]; void link(int L,int R) //将节点L和R连接起来,L在左,R在右 { iright[L]=R; ileft[R]=L; } int main() { scanf("%d%d",&n,&m); //建立双向循环链表,链表中有n+1个节点:0,1

崆若的水题之--矩阵乘法(SSDFOJ0016)

http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=16 输入n个矩阵的维度和一些矩阵链乘的表达式,输出乘法的次数.如果乘法无法进行,输出error.假定A是m*n矩阵,B是n*p矩阵,则乘法的次数为m*n*p.如果矩阵A的列数不等于矩阵B的行数,则这两个矩阵无法进行乘法运算.例如:A是50*10的,B是10*20的,C是20*5的,则 A(BC)的乘法次数为10*20*5(BC的乘法次数)+50*10*5(A(BC)的乘法次数)=3

崆若的水题之--你绝对看不懂题干的并查集#2(转载自CHX的博客)

试题描述 WZJ又有一个问题想问问大家.WZJ用数据生成器生成了一个虚拟旅游区.这个旅游区由N个城市构成,标号从1到N,这些城市之间由M条双向道路连接.其中每个城市有一个游乐场,游客可以花costi的钱数去城市i的游乐场玩,并获得happyi的高兴值,但对于一个游乐场,游客只能去玩至多一次.因为虚拟旅游区的内存有限,有时候WZJ被迫在系统中删去一些边,当然WZJ可能忘记一些已被删去的边.另外有些同学想来体验,WZJ会给他money的钱数,并把他送到城市x,他能通过未删除的道路去一些城市的游乐场玩

2015南阳CCPC L - Huatuo&#39;s Medicine 水题

L - Huatuo's Medicine Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description Huatuo was a famous doctor. He use identical bottles to carry the medicine. There are different types of medicine. Huatuo put medicines into the bottles and chain these b

sdut 2841 Bit Problem (水题)

题目 贴这个题是因为看题解有更简单的方法, 我做的时候是直接算的, 也很简单. 贴一下题解吧: 如果一个整数不等于 0,那么该整数的二进制表示中至少有一位是 1. 这个题结果可以直接输出 x - (x&(x-1)); 因为x-1 之后二进制下,就是最右边的1变成了0, 最右边的1的 右边所有的0变成了1, 不影响最左边. 我的代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4

sdut 2413:n a^o7 !(第三届山东省省赛原题,水题,字符串处理)

n a^o7 ! Time Limit: 1000MS Memory limit: 65536K 题目描述 All brave and intelligent fighters, next you will step into a distinctive battleground which is full of sweet and happiness. If you want to win the battle, you must do warm-up according to my inst

杭电(hdu)2053 Switch Game 水题

Switch Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 13113    Accepted Submission(s): 7970 Problem Description There are many lamps in a line. All of them are off at first. A series of o

4.7-4.9补题+水题+高维前缀和

题目链接:51nod 1718 Cos的多项式  [数学] 题解: 2cosx=2cosx 2cos2x=(2cosx)^2-2 2cos3x=(2cosx)^3-3*(2cosx) 数归证明2cos(nx)能表示成关于2cosx的多项式,设为f(n) f(1)=x,f(2)=x^2-2(其中的x就是2cosx) 假设n=1~k时均成立(k>=3) 当n=k+1时 由cos((k+1)x)=cos(kx)cos(x)-sin(kx)sin(x) cos((k-1)x)=cos(kx)cos(x)