365体育官网意味着从今弯道xj到弯道yj有同样修就为直道。256 MB

解析

管高度进行改动时,一定是拿它们修改成原来数组中的数字是最好美的。因为任以数字加减多少,总是当其与边际的数字同样大是极致优良的。因为如此会正好满足单调性(两屡次等)并且改变的数值最小。有或前面修改的数字在后出现如改变的情状,所以她起或得到到原数组中的其他一个数字。然后预处理排序一下到手稳步的数组b[]。于是可以形容来dp方程:f[i][j]表示前i个数、末尾的累改成为了第j老的数之最好小代价,则f[i][j]=min(f[i-1][k])+abs(a[i]-b[j]),1<=k<=j。但是如此是n^3的,所以还要长一个优化:我们算min(f[i-1][k])是O(n)的,但是这个是齐一致步的状态,所以可以于高达等同步直接保存min(f[i-1][k]),用类似前缀和的方。最后不可知忘记了把b[]倒一下呼吁下降之。

样例数据

样例输入 样例输出

5 3

0

1

0

1 4

2 5

4 5

3 5

2

 

 

 

 

 

 

 

 

 

 

样例数据

样例输入 样例输出

3
3 10 2
8 4 2
2 5 2

4

 

 

 

 

 

输入

率先执行包含两独正整数m, n,其中n是纸牌的个数,m是结点总数。结点编号吧1,2,…,m,其中编号1,2,… ,n是纸牌。以下n行每行一个0还是1的整数(0代表黑色,1代表白色),依次为c[1],c[2],…,c[n]。以下m-1行每行两只整数a,b(1<=a < b <= m),表示结点a和b 有度相连。

输入

率先实践包含2只整数N,M。N表示都的数目,M表示有向无尽的数码。
连通下m行,每行两只数A,B,表示从A到B有一致长达有向边。

题目分析

当主题当中,题目并不曾给出树的一干二净节点,于是首先想到:第一步一定是寻找根……好吧,这个思路是拂的,在最后我们见面发觉:无论选择哪一个节点作为根本,都不见面影响答案和染状态。比如,当前选取一个节点x为根来无比优解,y为其有一个底小子节点,x和y不见面同色——同色必然不呢极端优解,如果非同色,y转化为x的子,这样定不见面影响无与伦比优解。

由发现于一个子树中,不可能在个别只颜色各异的触及不满足条件,我们可以拓展如下概念:
f[u][0]意味着因u为根本节点的子树中无有无满足条件的不过小染色节点数;

f[u][1]意味着坐u为彻底节点的子树中存在叫染为0的节点不满足条件时的最为小染色节点数;

f[u][2]表示坐u为彻底节点的子树中设有于染为1底节点不满足条件时的极小染色节点数;

对此:tmp_1=∑(f[v][1]);   tmp_2=∑(min(f[v][0],f[v][1]));  
tmp_3=∑(min(f[v][0],f[v][2]));

经而得:f[u][0]=min(tmp_1,tmp_2+1,tmp_3+1);  
f[u][1]=min(tmp_2,tmp_3+1);   f[u][2]=min(tmp_2+1,tmp_3);

输入

第1尽:Mirko的恋人再三N
(2 ≤ N ≤ 200 000)
紧接下N行,每行3个数,表示:
x, y, and P (0 ≤ x, y, P ≤ 200 000). 朋友以Mirko送票之次第为出

STD Code

#include<cstring>
#include<cstdio>
#include<algorithm>

#define MAXN 10010

using namespace std;

struct node_a
{
    int head;
}V[MAXN];

struct node_b
{
    int v;
    int w;
    int next;
}E[MAXN];

int top;

void init()
{
    memset(V,-1,sizeof(V));
    top=0;
}
void add_edge(int u,int v,int w)
{
    E[top].v=v;
    E[top].w=w;
    E[top].next=V[u].head;
    V[u].head=top++;
}
int dp[MAXN][3];
void dfs1(int u)
{
    int biggest=0,bigger=0;
    for(int i=V[u].head;~i;i=E[i].next)
    {
        int v=E[i].v;
        dfs1(v);
        int tmp=dp[v][0]+E[i].w;
        if(biggest<=tmp)
        {
            bigger=biggest;
            biggest=tmp;
        }
        else if(bigger<tmp)
        {
            bigger=tmp;
        }
    }
    dp[u][0]=biggest;
    dp[u][1]=bigger;
}
void dfs2(int u)
{
    for(int i=V[u].head;~i;i=E[i].next)
    {
        int v=E[i].v;
        dp[v][2]=max(dp[u][2],dp[v][0]+E[i].w==dp[u][0] ? dp[u][1] : dp[u][0])+E[i].w;
        dfs2(v);
    }
}
int main()
{int n;
    scanf("%d",&n);
    init();
    for(int v=2;v<=n;v++)
    {
        int u,w;
        scanf("%d%d",&u,&w);
        add_edge(u,v,w);
    }
    dfs1(1);
    dp[1][2]=0;
    dfs2(1);
    for(int i=1;i<=n;i++)
    {
        printf("%d\n",max(dp[i][0],dp[i][2]));
    }
    return 0;
}

输出

出口包含n行.
第i实践表示对于离开编号为i的节点最远之节点和拖欠节点的相距Si(1≤i≤n)。

【SinGuLaRiTy-1015】 Copyright (c) SinGuLaRiTy 2017. All Rights
Reserved.

题材叙述

身临其境选举,总统而当都市1以及都市2做演讲。他乘机汽车完成巡回演讲,从1启程,途中要通过都2,最后要返回城市1.特勤局对总统而经的所有城市监控。为了让用最小,必须使监控之都市最为少。求最少要监督的城池。
共计发N个城市,有M条有向边。(0<=N,M<=200)
有N从1起身途中要通过2,最后只要回到1底途径中至少要经过的接触之数。

STD Code

#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>

#define MAXN 10010
#define INF 0x3f3f3f3f

using namespace std;

vector <int> vec[MAXN];

int n,m;
int color,f[MAXN][10];
bool vis[MAXN];

void dp(int u)
{
    vis[u]=1;
    int tmp_1=0,tmp_2=0,tmp_3=0;
    bool flag=0;
    for(unsigned int i=0;i<vec[u].size();i++)
    {
        int v=vec[u][i];
        if(vis[v])
            continue;
        dp(v);
        tmp_1+=f[v][0];
        tmp_2+=min(f[v][0],f[v][1]);
        tmp_3+=min(f[v][0],f[v][2]);
        flag=1;
    }
    if(flag)
    {
        f[u][0]=min(tmp_1,min(tmp_2+1,tmp_3+1));
        f[u][1]=min(tmp_2,tmp_3+1);
        f[u][2]=min(tmp_2+1,tmp_3);
    }
}
int main()
{
    int u,v;
    scanf("%d%d",&n,&m);
    memset(f,INF,sizeof(f));
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&color);
        f[i][0]=1;
        f[i][color+1]=0;
    }
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&u,&v);
        vec[u].push_back(v);
        vec[v].push_back(u);
    }
    dp(n);
    printf("%d\n",f[n][0]);
    return 0;
}

 

Time : 2017-04-04

解析

自家用底凡Floyd:t[i]表示第i个弯道时,d[i][j]表示第i独弯道到第j个弯道时,初始化INF。接着下floyd求出各个弯道之间直道最缺乏日,记得要加上连接弯道的直道时间。题目要求要经1弯道底无比差里程都必备发出直接道路,说明必要发出零星只弯道连接而变成加上直道,则枚举2到n所有点,取其d[1][i]+t[i]+d[i][1]+t[1]尽小价。还需要判定是否有解即判断及INF的涉嫌。

如若数额更胜一些以来,就该用两糟糕Dijkstra(正奔相反朝每一蹩脚),然后枚举中间点来摘取答案。

STD Code

#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<algorithm>

#define MAXN 3010
#define INF 0x3f3f3f3f

using namespace std;

struct node
{
    int v;
    int va;
};

vector <node> tu[MAXN];
int mo[MAXN],f[MAXN][MAXN],get[MAXN];
int n,m;

void add(int u,int v,int va)
{
    node p;
    p.v=v;
    p.va=va;
    tu[u].push_back(p);
}
void init()
{
    int tmp_1,tmp_2,tmp_3;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n-m;i++)
    {
        scanf("%d",&tmp_1);
        for(int j=1;j<=tmp_1;j++)
        {
            scanf("%d%d",&tmp_2,&tmp_3);
            add(i,tmp_2,tmp_3);
        }
    }
    for(int i=n-m+1;i<=n;i++)
    {
        scanf("%d",&mo[i]);
    }
}
int dp(int x)
{
    if(x>n-m)
    {
        f[x][1]=mo[x];
        get[x]=1;
        return get[x];
    }
    for(unsigned int i=0;i<tu[x].size();i++)
    {
        get[x]+=dp(tu[x][i].v);
    }
    for(unsigned int i=0;i<tu[x].size();i++)
    {
        for(int j=get[x];j>=1;j--)
        {
            for(int k=min(j,get[tu[x][i].v]);k>=0;k--)
            {
                f[x][j]=max(f[x][j],f[tu[x][i].v][k]+f[x][j-k]-tu[x][i].va);
            }
        }
    }
    return get[x];
}
int main()
{
    init();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            f[i][j]=-INF;
        }
    dp(1);
    int ans=0;
    for(int i=1;i<=m;i++)
    {
        if(f[1][i]>=0)
        {
            ans=max(ans,i);
        }
    }
    printf("%d",ans);
    return 0;
}

输出

起码要监督之城市之数据。

题材叙述

一个电视网络计划转播一集重要的足球比赛。网络中之传输点和接收点(即用户)可以表示同样棵树。这株树之清是一个传输点,它将转播比赛。树之叶节点是唯恐只要受这会竞技的用户(他本来好选取未看比赛,这样就算不用交款)。其他非根节点,非叶节点的高中级节点也数据的中转站。将一个信号于一个传点污染至其它一个传输点的花是加的。整个转播的用便是各国一个传费用的总数。每一个用户(叶节点)都备交付得之钱来拘禁这会竞技。电视网络商家只要控制是否要吃这用户提供电视信号。例如:给一个节点传输信息之花太怪,而异乐于的付款也生少时,网络店铺或者选择未被他转播比赛。写一个序,找到一个传方案要尽多的用户会见到转播比赛,且转播的开销不超过所有接受信号用户之缴费。

[Baltic 02] 速度限制 (Speed)

仲题:电视转播

样例数据

样例输入1 样例输出1

4 4
+…
….
….
V..J

3
样例输入2 样例输出2

4 5
…..
.+++.
.+.+.
V+.J+

0

 

 

 

 

 

 

 

 

 

 

 

样例数据

样例输入 样例输出

3

1 1

1 2

2

3

3

 

 

 

 

 

输出

唯有一行整数,表示从0到D经过的市。输出的相继必须依卿通过这些都会的逐一,以0开始,以D结束。仅来一致长达最抢路线。

对此有着的问题:Time Limit:1s  |  Memory:256 MB

题材叙述

于这忙的社会面临,我们累不再去选最好短的征途,而是选择最为抢之门径。开车时每条道路的限速成为极端要紧之题目。不幸之是,有局部限速的标志丢失了,因此你无法获悉该开多快。一种可以分辨的缓解方案是,按照原先的速行驶。你的职责是算两地间的无比抢路线。
你以抱同卖现代化都市之道路交通信息。为了使问题简化,地图才囊括路口及征途。每条道是有于的,只连接了两条道路,并且极多才出同等块限速标志,位于路的起点。两地A和B,最多只是发生相同长道路从A连接到B。你得使加速能够以转瞬到位而不见面起交通堵塞等气象影响您。当然,你的车速不克超越目前底速度限制。

问题叙述

深受同样棵m个结点的无根树,你可以挑选一个度数大于1之结点作为根本,然后让一部分结点(根、内部结点和叶子均只是)着坐黑色或白色。你的着色方案应保证根结点到每个叶子的简要路径上还至少含有一个死里逃生结点(哪怕是这叶子本身)。

对于每个叶结点u,定义c[u]也打根结点到u的简路径上最终一个有色结点的颜料。给闹每个c[u]的价,设计着色方案,使得着色结点的个数尽量少。

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<iostream>
#include<queue>

#define MAXN 250000
#define MAXM
#define INF 0x3f3f3f3f

typedef long long int LL;

using namespace std;

struct node
{
    int v;
    node *next;
}*adj[MAXN+10],Edges[MAXN*4],*New=Edges;

const int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

void addedges(int u,int v)
{
    node *p=++New;
    p->v=v;
    p->next=adj[u];
    adj[u]=p;

    p=++New;
    p->v=u;
    p->next=adj[v];
    adj[v]=p;
}

int id[510][510];
int weath[MAXN+10];

struct point
{
    int x,y;
    point(){}
    point(int a,int b):x(a),y(b){}
};

int N,M;
int Sx,Sy,Tx,Ty;

queue<point>que1;

void bfs()
{
    point now;
    while(!que1.empty())
    {
        now=que1.front();que1.pop();
        int nx,ny;
        for(int i=0;i<4;++i)
        {
            nx=now.x+dir[i][0],ny=now.y+dir[i][1];
            if(nx<1||ny<1||nx>M||ny>N)
                continue;

            if(weath[id[nx][ny]]>weath[id[now.x][now.y]]+1)
            {
                weath[id[nx][ny]]=weath[id[now.x][now.y]]+1;
                que1.push(point(nx,ny));
            }
        }
    }
}

struct data
{
    int pos,w;
    data(){}
    data(int a,int b):pos(a),w(b){}

    bool operator < (const data &a)const
    {
        return w<a.w;
    }
};

int dist[MAXN+10];
bool vis[MAXN+10];

priority_queue<data>que2;

int dijkstra()
{
    memset(dist,0x3f,sizeof(dist));
    while(!que2.empty())que2.pop();

    int S=id[Sx][Sy],T=id[Tx][Ty];
    dist[S]=weath[S];
    que2.push(data(S,0));

    data now;
    while(!que2.empty())
    {
        now=que2.top();que2.pop();

        if(vis[now.pos])
            continue;
        else
            vis[now.pos]=1;
        if(now.pos==T)
            return dist[now.pos];
        for(node *p=adj[now.pos];p!=NULL;p=p->next)
            if(dist[p->v]>min(dist[now.pos],weath[p->v]))
            {
                dist[p->v]=min(dist[now.pos],weath[p->v]);
                que2.push(data(p->v,dist[p->v]));
            }
    }

    return -1;
}

int main()
{
    scanf("%d%d",&M,&N);
    memset(weath,0x3f,sizeof(weath));
    char s[510];
    for(int i=1;i<=M;++i)
    {
        scanf("%s",s+1);
        for(int j=1;j<=N;++j)
        {
            id[i][j]=(i-1)*N+j;
            if(s[j]=='+')
            {
                weath[id[i][j]]=0;
                que1.push(point(i,j));
            }
            else if(s[j]=='V')
                Sx=i,Sy=j;
            else if(s[j]=='J')
                Tx=i,Ty=j;
        }
    }
    for(int i=1;i<=M;++i)
        for(int j=1;j<=N;++j)
        {
            if(j!=N)
                addedges(id[i][j],id[i][j+1]);
            if(i!=M)
                addedges(id[i][j],id[i+1][j]);
        }
    bfs();
    printf("%d\n",dijkstra());
    return 0;
}

题材叙述

受一定一株有n个节点的塑造,求每个节点到另外节点的极致酷距。

[CQBZOJ 1550] 避开怪兽

输出

才一个勤,即着质量结点数之顶小价。

Code

#include<cstring>
#include<cstdio>
#include<algorithm>

#define MAXN 10010

using namespace std;

struct node_a
{
    int head;
}V[MAXN];

struct node_b
{
    int v;
    int w;
    int next;
}E[MAXN];

int top;

void init()
{
    memset(V,-1,sizeof(V));
    top=0;
}
void add_edge(int u,int v,int w)
{
    E[top].v=v;
    E[top].w=w;
    E[top].next=V[u].head;
    V[u].head=top++;
}
int dp[MAXN][3];
void dfs1(int u)
{
    int biggest=0,bigger=0;
    for(int i=V[u].head;~i;i=E[i].next)
    {
        int v=E[i].v;
        dfs1(v);
        int tmp=dp[v][0]+E[i].w;
        if(biggest<=tmp)
        {
            bigger=biggest;
            biggest=tmp;
        }
        else if(bigger<tmp)
        {
            bigger=tmp;
        }
    }
    dp[u][0]=biggest;
    dp[u][1]=bigger;
}
void dfs2(int u)
{
    for(int i=V[u].head;~i;i=E[i].next)
    {
        int v=E[i].v;
        dp[v][2]=max(dp[u][2],dp[v][0]+E[i].w==dp[u][0] ? dp[u][1] : dp[u][0])+E[i].w;
        dfs2(v);
    }
}
int main()
{int n;
    scanf("%d",&n);
    init();
    for(int v=2;v<=n;v++)
    {
        int u,w;
        scanf("%d%d",&u,&w);
        add_edge(u,v,w);
    }
    dfs1(1);
    dp[1][2]=0;
    dfs2(1);
    for(int i=1;i<=n;i++)
    {
        printf("%d\n",max(dp[i][0],dp[i][2]));
    }
    return 0;
}

输入

输入文件的率先行包含两只整数N和M(2<=N<=3000,1<=M<=N-1)。N,M表示分别代表树之节点数和思念看到比赛的用户数。树之到底节点用1代表,中间节点的标为2~N-M,用户之节点标号为N-M+1~N。接下来的N-M行表示传输点的音信(依次是节点1,2……):
K A1 C1 A2 C2 …… Ak Ck
表示一个传输点将信号传给K个用户,每一个含有两单数A和C,A表示传输点或用户之节点号,C表示传输的费。最后一履含有用户之数据,有M个整数表示他们看这会交锋愿意的付费。

解析

坐要求一律漫长路让怪兽最近底偏离太远。 
于是乎先处理发生每一个触及及怪兽的近期去,因为运动得进一步远及怪兽距离的最小值未会见转移死,具有单调性,然后跑dijsktra就实行了。

样例数据

样例输入 样例输出

5 3

2 2 2 5 3

2 3 2 4 3

3 4 2

2

5 3

2 2 2 5 3

2 3 2 4 3

4 4 2

3

9 6

3 2 2 3 2 9 3

2 4 2 5 2

3 6 2 7 2 8 2

4 3 3 3 1 1

5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

输入

第1推行:2只整数N和M(1 ≤
N, M ≤ 500) 接下来N行,每行M个字符,可能是’.’, ‘+’, ‘V’, ‘J’等.
数据保证单独包含1单’V’ 和1只 ‘J’ ,至少有1只’+’

问题分析

当时道题是考前一天课上讲话的题材,如果本身没记错的口舌应该是HDU
2196之原题。让自己兴奋的凡,尽管当时道题没有叫布置上作业中,但我昨天便曾经当HDU上AC了这道题,再从一全代码也是相当之自由自在,一种优越感油然而生……

下面,让咱们来看看这道题的思路:对于其余一个节点M,我们好将偏离其极其远的点的职务分为两好像:①在以M为根节点的子树中,我们借而这个种状况下之极致远距离吗maxdis_down;②在为M为根节点的子树之外,我们借而这个种植状况下的绝远距离呢maxdis_up。显而易见的凡,此时夫点之极端远距离ans[M]就为max(maxdis_down,maxdis_up)。我们重点看第二种植状况:maxdis_up=M到其父亲节点L的去dis(M,L)+ans[L]。对之,我们可定义一个dp[MAXN][3]的数组:

f[i][0]代表顶点为i的子树中,距离顶点i的最为远距离(对应第一种植状态);

f[i][1]代表i到那个父亲节点的偏离+其大之顶远距离(对应第二种植情形);

f[i][0]实际不需要DP,dfs就可求解(本次dfs也求出次长距离);对于f[i][1],我们采取由父节点交子节点的方针。

要有同L节点,它来n个子节点,我们就此Vi来表示。

这时,我们同时如果分开情况来讨论了:

①若Vi不是L的最好丰富路所通过节点,有f[Vi][1]=dis(Vi,L)+max(f[L][0],f[L][1]);

②一旦Vi是L的最丰富路所通过节点,Vi的顶丰富路就是无克再于算,我们尽管使“退而求其次”,使用第二增长的路径Sec_dis,此时有f[Vi][1]=dis(Vi,L)+max(Sec_dis,f[L][1])。

解析

率先,对于自由两座城,我们要算是出distance[a][b],即由市a到城池b的偏离,如果简单座城市中没有门路,我们就是拿distance设置也INF。对于这同样操作,Floyd就得缓解了。
俺们就好据此dp[a][b]来代表路径1->a->b->1及监控之顶少都数目(注意:a和b也足以一如既往)。接下来,我们尽管可用来下式子来完成dp[a][b]到dp[x][y]的状态转移了:
dp[x][y]=dp[a][b]+distance[b][x]+distance[x][y]+distance[y][a]-1

365体育官网 1

倘我们采用Dijkstra对持有的(a,b)状态进行查找,我们的靶子状态就是dp[2][2]。

输出

输出包含n行.
第i履表示于离开编号为i的节点最远之节点和该节点的相距Si(1≤i≤n)。

输出

第1实行:1独整数,表示Mirko必须移动之极致少运动步数

输出

独自一行包含一个平头,最可怜之用户数。

样例数据

样例输入 样例输出

7
1
3
2
4
5
3
9

3

 

 

 

 

 

 

 

 

题材分析

只顾到了问题结尾处“找到一个传输方案要尽多的用户能够望转播比赛,且转播的用不超越所有接收信号用户之缴费”,这种熟悉的觉得——一定是01背包问题,一定是这般的!用户就一定给是品,传输费用相当于是代价,总交款就是背包的容量……于是,题目类型确定:DP+01背包问题。

概念一个f[MAXN][MAXN]数组,f[l][m]意味着:在根节点为l的子树中,将m个用户接入客户端所能赢得的太要命报酬。DP方程应该是较好掌握的,树形DP套上一个01背包的思绪就是尽了:f[u][j+k]=max(f[u][j+k],f[u][j]+f[v][k]-edge[i].w)

输出

第1尽:
输出1独刚刚整数,表示FJ把路修成高度不腾还是可观不降的无限小花费

<通过求树的直径解决>

铸就的直径是什么?就是于同蔸树上是的星星点点沾间的极远距离所经的路。例如:

365体育官网 2

以该图中,树之直径,即距离最丰富的点滴碰中路径也:7、5、2、1、3、6

以此间我们拿用一个结论:对于自由一个培训被之节点吧,距离她不过远的点定是及时株树之直径的星星点点独端点中的一个。【翔说明】

经过者结论,我们就是得先行对个别点展开dfs求最远点,确定树之直径的鲜单端点,然后针对培养被之接触进展dfs求出长即可。

样例数据

样例输入 样例输出

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

6

 

 

 

 

 

 

 

 

 

数规模

30% n≤100 

100% n≤10000

【SInGuLaRiTy-1027】
Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.

第一题:最长链(HDU 2196 Computer)

问题叙述

老的赛道令国际汽联十分遗憾。汽联命令主办方就对赛道进行调整,否则将取消该主办权。主办方当然不能不立即开始走路。

赛道测评人员由此了三上三夜间的数额收集,选出了多少可应用的征途及每道路行驶所欲的工夫。这些道路包括多直道和弯道,每个直道连接两单例外之弯道都也单向,两独弯道之间或发生多长长的直道,通过直道和弯道都亟待一定的流年。主办方打算于这些可用道路中选出一部分作赛道。赛道是由直道和弯道交替组成的一模一样缠绕,赛道可反复经同修弯道,因为主办方可以透过架设立交桥底不二法门避免撞车。为了要比赛更加优良,主办方希望选择相同长达单圈时间太短的赛道,由于观众席的职于弯道1,所以赛道必须经弯道1(赛道至少要含有一漫长直道)。

老三开:叶子的颜料(CQOI 2009)

题材叙述

于得一株有n个节点的造,求每个节点到其他节点的最好老距离。

输入

输入第一执是一个理所当然数n(n≤10000);

联网下去 (n−1) 行描述:第i实行包含两个当数 ,
表示编号为i的节点连接到的节点编号与就长达网线的尺寸..距离总长不见面跳10^9.
每行中之点滴个数字用空格隔开。

[BZOJ 1592] 路面修整 (Making the Grade)

解析

每一个Mirko的情人还是由X,Y,P描述的。注意到,与一个恋人的也许的会合点形成了一个因(X,Y)为主干的正方形,更适于地游说,是一个相对顶点在(X-P,Y-P)和(X+P,Y+P)的正方形。
那么,现在之题材虽为简化为寻本梯次经过所有正方形的极其缺乏可能路线。
对此K
(1<=K<=N),我们着想以梯次访问正方形1~K的兼具可能的无限缺乏路径。设S(K)为这些途径的最终节点的集合,即我们坐最佳策略访问前K个朋友后方可结束的具有职位。我们再设d(K)为这些极短缺路径的尺寸。
留意到,S(1)的点所组成的造型恰好是首先独对象所对应的正方形,因为咱们于之刚刚方形的任何点都足以开(并结)对之心上人之拜访,且当前之路子长度为0。
咱们的程序一旦连续找到S(2)、S(3)……S(N)。我们见面意识,所有的汇聚都是矩形。那么现在,我们就要看哪些由S(K)找到S(K+1)。
令D代表S(K)中的随机一点到S(K+1)(即我们下一个使拜访的食指)的极其短距离。那么d(K+1)=d(K)+D。
假如我们当四独趋势及针对矩形S(K)扩展D个单位,我们沾最佳访问前K个朋友更为自由方向移动D个单位后方可抵达的所有点。因此,扩展的矩形与第(K+1)个对象所对应的正方形的夹就是咱走d(K)+D(根据D的定义,这个交集一定不是空集)个单位去后能够及第(K+1)个对象见面的点。那么,这个交集就刚刚是S(K+1)。由于此交集是由于一个矩形和一个恰恰方形得到的(正方形和矩形的交点都同同等之轴对其),这个交集就势必是一个矩形。(还是抓不知道?画画图吧)
末的消除就只是以寻找S(2),S(3),……,S(N)时得的拥有D值的以及,这恰就是d(N)。

样例数据

样例输入 样例输出

6 15 1
0 1 25 68
0 2 30 50
0 5 0 101
1 2 70 77
1 3 35 42
2 0 0 22
2 1 40 86
2 3 0 23
2 4 45 40
3 1 64 14
3 5 0 23
4 1 95 8
5 1 0 84
5 2 90 64
5 3 36 40

0 5 2 3 1

 

 

 

 

 

 

 

 

 

 

 

 

 

Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>

#define mod 1000007
#define INF 0x7fffffff

using namespace std;

int a[5001],s[5001];
int f[2001][2001];
int sav[2001][2001];
int from[2001];
int head[mod];

struct node
{
    int v,next;
}hashing[100000];

int cnt,len,ans=2147483647;

inline int read()
{
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9')ch=getchar();
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x;
}

inline void ins(int u,int w)
{
    hashing[++cnt].v=w;
    hashing[cnt].next=head[u];
    head[u]=cnt;
}

int main()
{
    int n=read();
    for(int i=1;i<=n;i++) 
    {
        a[i]=read();
        int now=a[i]%mod;bool mark=0;
        for(int j=head[now];j;j=hashing[j].next)
        {
            if(hashing[j].v==now)
            {
                mark=1;
                break;
            }
        }
        if(mark) 
            continue;
        ins(now,a[i]);
        s[++len]=a[i];
    }
    sort(s+1,s+len+1);
    for(int i=1;i<=n;i++)
    {
        sav[i][0]=2147483647;
        for(int j=1;j<=len;j++)
        {
            f[i][j]=2147483647;
            int add=abs(a[i]-s[j]);
            f[i][j]=sav[i-1][j]+add;
            sav[i][j]=min(sav[i][j-1],f[i][j]);
        }
    }
    for(int i=1;i<=len;i++)
        ans=min(f[n][i],ans);
    int rev[len+1];
    for(int i=1;i<=len;i++)
        rev[i]=s[len-i+1];
    for(int i=1;i<=len;i++)
        s[i]=rev[i];
    memset(f,0,sizeof(f));
    for(int i=1;i<=n;i++)
    {
        sav[i][0]=2147483647;
        for(int j=1;j<=len;j++)
        {
            f[i][j]=2147483647;
            int add=abs(a[i]-s[j]);
            f[i][j]=sav[i-1][j]+add;
            sav[i][j]=min(sav[i][j-1],f[i][j]);
        }
    }
    for(int i=1;i<=len;i++)
        ans=min(f[n][i],ans);
    printf("%d",ans);
    return 0;
}

Code

#include<cstdio>
#include<algorithm>
#include<iostream>

using namespace std;

struct rectangle
{
    int x1,x2,y1,y2;
    rectangle(){}
    rectangle(int x,int y,int p)
    {
        x1=x-p;
        x2=x+p;
        y1=y-p;
        y2=y+p;
    }
};

int main()
{
    int n;
    scanf("%d",&n);
    int x,y,p;
    scanf("%d%d%d",&x,&y,&p);
    rectangle S(x,y,p);
    long long ans=0;
    for(int i=1; i<n; ++i)
    {
        scanf("%d%d%d",&x,&y,&p);
        rectangle A(x,y,p );
        int D=max(max(A.x1-S.x2,S.x1-A.x2),max(A.y1-S.y2,S.y1-A.y2));
        if(D<0)
            D=0;
        ans+=D;
        S.x1-=D;
        S.x2+=D;
        S.y1-=D;
        S.y2+=D;
        rectangle Part;
        Part.x1=max(S.x1,A.x1);
        Part.x2=min(S.x2,A.x2);
        Part.y1=max(S.y1,A.y1);
        Part.y2=min(S.y2,A.y2);
        S=Part;
    }
    cout<<ans;
    return 0;
}

Code

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>

#define maxn 1010
#define INF 0x3f3f3f3f

int n,m,a,b,c;
int dist[maxn][maxn];
int ans=INF;
int t[maxn];

using namespace std;

int main()
{

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&t[i]);
    for(int i=1;i<=m;i++)
        for(int j=i+1;j<=n;j++)
            dist[i][j]=dist[j][i]=INF;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&a,&b,&c);
        dist[a][b]=min(c+t[a],dist[a][b]);
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
                dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
    for(int i=2;i<=n;i++)
        ans=min(ans,dist[1][i]+dist[i][1]);
    if(ans<INF)
        printf("%d",ans);
    else
        puts("-1");
    return 0;
}

题目叙述

Mirko要让爱人等送音乐会门票。朋友之小但代表为二维平面的网格。Mirko在行动时,可以朝8只方向动,每次都是整数坐标。他每一样步于及、下、左、右以及4单对角方向活动一格。
每个朋友的舍可是代表也面及之点(x,y)。当Mirko到某某朋友家送票时,朋友吗可以活动出来迎接他,也得以望8只方向行进。因此,Mirko以及这朋友最好多足以离他家P步远的位置相遇。P随每个朋友不同。
Mirko的开始位置及顶位置还一无所知。

题目要求要来:Mirko送完所产生票的顶少动步数。

样例数据

样例输入 样例输入

3 6
1
1
2
1 2 3
2 3 5
3 1 1
3 2 1
2 1 10
1 3 15

13

 

 

 

 

 

 

 

 

 

Code

#include<iostream>
#include<cstdio>

using namespace std;

const int maxv=501;
const int maxn=151;
const int INF=10000000;

double T[maxv*maxn];
int A[maxv*maxn];
int pos[maxv*maxn];
int Size;

int g[maxn],rd[maxn][maxn],v[maxn][maxn],w[maxn][maxn];
int path[maxv*maxn],visit[maxv*maxn];
int n,m,D;

void heapup(int k)
{
    while (k>1 && T[A[k]]<T[A[k>>1]])
    {
        swap(pos[A[k>>1]],pos[A[k]]);
        swap(A[k>>1],A[k]);
        k=k>>1;
    }
}

void heapdown(int k)
{
    int lson,rson;
    int minest=k;
    do
    {
        k=minest;
        lson=k<<1; rson=(k<<1)|1;
        if (lson<=Size && T[A[lson]]<T[A[minest]]) minest=lson;
        if (rson<=Size && T[A[rson]]<T[A[minest]]) minest=rson;
        swap(pos[A[k]],pos[A[minest]]);
        swap(A[k],A[minest]);
    }while(minest!=k);
}

void Insert(int Hash)
{
    Size++;
    A[Size]=Hash;
    pos[Hash]=Size;
    heapup(Size);
}

int getmin()
{
    int rt=A[1];
    swap(pos[A[1]],pos[A[Size]]);
    swap(A[1],A[Size]);
    Size--;
    if(Size>0)
        heapdown(1);
    return rt;
}

void print(int Hash)
{
    if(Hash==-1)
        return;
    print(path[Hash]);
    int np=Hash%n;
    printf("%d ",np);
}

void dijkstra()
{
    int Hash;
    int shash,sv,sn,dhash,dv,dn;
    double dt;
    for (int i=0;i<=n*maxv;i++)
    {
        T[i]=INF;
        visit[i]=0;
    }
    Hash=n*70+0;
    T[Hash]=0.0;
    path[Hash]=-1;
    Insert(Hash);
    while(Size!=0)
    {
        shash=getmin();
        sn=shash%n;
        sv=shash/n;
        visit[shash]=2;
        if(sn==D)
            break;
        for (int i=1;i<=g[sn];i++)
        {
            dn=rd[sn][i];
            dv=v[sn][i]==0?sv:v[sn][i];
            dhash=n*dv+dn;
            if (visit[dhash]<2)
            {
                dt=T[shash]+(double)w[sn][i]/(double)dv;
                if (dt<T[dhash])
                {
                    T[dhash]=dt;
                    path[dhash]=shash;
                    if (visit[dhash]==0)
                    {
                        Insert(dhash);
                        visit[dhash]=1;
                    }
                    else
                        heapup(pos[dhash]);
                }
            }
        }
    }
    print(shash);
}

int main()
{
    int ad,bd;
    scanf("%d%d%d",&n,&m,&D);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&ad,&bd);
        g[ad]++;
        rd[ad][g[ad]]=bd;
        scanf("%d%d",&v[ad][g[ad]],&w[ad][g[ad]]);
    }
    dijkstra();
    return 0;
}

 

Time: 2017-07-20

输入

输入第一执行是一个本来数n(n≤10000);

连着下 (n−1)
行描述:第i执包含两单当数 ,
表示编号为i的节点连接至之节点编号和即时漫长网线的尺寸..距离总长不会见超过10^9.
每行中之点滴单数字用空格隔开。

题材叙述

Farmer
John打算好好修一下农场受某个条崎岖之土路。按奶牛们的求,修好后底路面高度应单调上升还是干燥下降,也就是说,高度上升及高度降低之路段不可知而且出现于修好的路途被。
整修路让分成了N段,N个整数A_1, … , A_N (1 <= N <=
2,000)依次描述了各级一样段总长的惊人(0 <= A_i <= 1,000,000,000)。Farmer
John希望找到一个恰好好含N个元素的莫起要无下滑序列B_1, … ,
B_N,作为修过的里程遇每个路段的可观。由于用诸一样段落路垫高还是打低一个单位之消费一样,修路的总支出可以表示为:
|A_1 – B_1| + |A_2 – B_2| + … + |A_N – B_N| 请你算一下,Farmer
John在这项工程达到的无限小开是略。Farmer
John向你保证,这个开不会见超过2^31-1。

输出

一个整数s,表示单圈时间最缺的赛道的单圈时间,若无脱则输出-1。

[HDU 2196] 最长链 (Computer)

Code

#include<algorithm>
#include<cstdio>

#define MAXN 210
#define INF 1000000

using namespace std;

int g[MAXN][MAXN];
int dist[MAXN][MAXN];
int n, m;

char done[MAXN][MAXN];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            g[i][j]= (i==j ? 0 : INF) ;
    for(int i=0;i<m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        g[--u][--v]=1;
    }
    for(int k=0;k<n;k++)
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            dist[i][j]=INF;
            done[i][j]=0;
        }
    dist[1][1]=1;
    for(;;)
    {
        int a=-1,b=-1;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            {
                if(done[i][j])
                    continue;
                if(a==-1||dist[i][j]<dist[a][b])
                {
                    a=i;
                    b=j;
                }
            }
        if(a==0&&b==0)
            break;
        done[a][b]=1;
        for(int c=0;c<n;c++)
            for(int d=0;d<n;d++)
            {
                if(c==a||c==b||d==a||d==b)
                    continue;
                dist[c][d]=min(dist[c][d],dist[a][b]+g[b][c]+g[c][d]+g[d][a]-1);
            }
    }
    printf("%d", dist[0][0]);
    return 0;
}

样例数据

样例输入 样例输出

3

1 1

1 2

2

3

3

 

 

 

 

 

数码规模

30%
n≤100 

100%
n≤10000

[COCI 2011-2012 Contest #7] 送票 (SETNJA)

解析

立马道题是考查前一天课上道的题目,如果自己从未记错的言语应该是HDU
2196的原题。让自身兴奋的凡,尽管就道题没有为摆上作业中,但本身昨天就是既于HDU上AC了当时道题,再打一整个代码也是一对一之自由自在,一种植优越感油然而生……

下,让我们来探就道题的思绪:对于任何一个节点M,我们可用距离她最远的触及之位置分为两像样:①于为M为彻底节点的子树中,我们借而这个种植情景下的不过远距离也maxdis_down;②于因M为根本节点的子树之外,我们借要这个种植状态下之极致远距离也maxdis_up。显而易见的是,此时这点之顶远距离ans[M]就为max(maxdis_down,maxdis_up)。我们最主要看第二种状态:maxdis_up=M到那个父亲节点L的离dis(M,L)+ans[L]。对这,我们得以定义一个dp[MAXN][3]的数组:

f[i][0]意味着顶点为i的子树中,距离顶点i的卓绝远距离(对应第一种情景);

f[i][1]意味着i到该大节点的离+其父亲的无限远距离(对应第二栽状态);

f[i][0]骨子里不待DP,dfs就不过求解(本次dfs也呼吁来次长距离);对于f[i][1],我们运用从父节点及子节点的方针。

如果发生一致L节点,它发出n个子节点,我们用Vi来代表。

此刻,我们以要分情况来谈谈了:

①若Vi不是L的卓绝丰富路所经节点,有f[Vi][1]=dis(Vi,L)+max(f[L][0],f[L][1]);

②设Vi是L的无限丰富路所经节点,Vi的最好丰富路就是非克重新于计算,我们虽使“退而求其次”,使用第二添加之路径Sec_dis,此时有f[Vi][1]=dis(Vi,L)+max(Sec_dis,f[L][1])。

<通过求树的直径解决>

扶植的直径是什么?就是以同等蔸树上有的点滴沾里的太远距离所经的路线。例如:

365体育官网 3

每当该图中,树的直径,即距离太丰富之星星沾内路径为:7、5、2、1、3、6

每当这边我们用采取一个定论:对于随意一个养被的节点吧,距离其极远之点一定是即刻棵树之直径的点滴只端点中的一个。【详见说明】

经此结论,我们就好事先对有限触及开展dfs求最远点,确定树之直径的蝇头个端点,然后针对培训被的接触进展dfs求出长即可。

输出

第1尽:1独整数,表示最好缺曼哈顿距离的无限大值

输入

第1行:
输入1个整数:N
第2..N+1行:
第i+1行为1个整数:A_i

解析

此,我们得以行使枚举出所有的情形,借助HASH来记录。
对于一个结点,我们要记录之出到达这个结点的时刻(Tips:并非当前最为小时间)、当前速度。所以,我们组织一个求HASH值的相:Hash=n(结点数)*v(到达这个结点的速)+当前结点。通过Hash值我们啊能够充分容易求得时间、速度。

想必我们会提出问题,这样求HASH值可以呢?会不见面不同之时跟结点编号也求得相同的HASH值。答案是早晚的,不会见。
证明:1.若v相同,结点编号不同,因为结点编号小于n,所以HASH值一定不一样;

2.若结点数码相同,v不同,因为结点编号小于n,所以v最小差值1啊非是会为此号码差值弥补的,所以HASH值一定非均等;

3.若结点,v不同,因为结点编号小于n,所以v最小差值1吧无是会就此数码差值弥补的,所以HASH值一定不等同。
发生矣这个事物,我们即便足以做Dijkstra了,当然,关键字还是是光阴。一般在Dijkstra中,我们找寻最小之一个第一字还是因此for,在就书里,这样做一定浪费时间,因为其并无单纯来150(n)个。我们考虑就此小根堆来促成。
下实现有就是比较易于了。

输入

第1推行:3单空格分开的整数N,M和D(2<=N<=150),N表示路口的数目,用0..N-1号。M是道路的总和,D表示若的目的地。
接下来的M行,每行描述一条道,每行有4独整数A(0≤A<N),B(0≤B<N),V(0≤V≤500)and
L(1≤L≤500),这漫长路是起A到B的,速度限制是V,长度也L。如果V是0,表示马上条路的限速未知。如果V不为0,则经过该路的时空T=L/V。否则T=L/Vold,Vold是你到该路口前面之速度。开始经常您放在0点,并且速度也70。

问题叙述

给来一个N行M列的地形图,地图形成一个有N*M个格子的矩阵。地图中之空地用’.’表示。其中一些格子有怪兽,用’+’表示。某人而打起点格子’V’走至极限格子’J’,他可发展、下、左、右四单趋势走。因此,起点与极端之间可来成百上千漫漫路。注意:即使是生怪兽之格子,他啊得倒上去。设路径上有格子的坐标为(R,C),某个怪兽的坐标为(A,B),那么它们中间的曼哈顿距离定义为:|R-A|

  • |C-B|
    显然,地图及恐怕发成千上万怪兽,路径上吗或过许多格子,每个格子到每个怪兽都足以算出之间的曼哈顿距离。问整长达途径中离怪兽的曼哈顿距离最小价最酷呢小?
     

输入

第一履行是个别独整数n,m(1<=n<=200,1<=m<=100000),分别表示弯道数和直道数。接下来n行,第i实践是一个整数ai(1<=ai<=1000),表示通过第i个弯道所耗费的辰。接下来m行,第j尽是三只整数xj,yj,bj(1<=xj,yj<=n,1<=bj<=1000),表示于弯道xj到弯道yj有一样久才为直道,且经该直道所耗费的工夫为bj。

[Vijos 1423] 最佳路径

[COCI 2011-2012 Contest #7] 总统演讲 (KAMPANJA)

相关文章