DAY1 [2] SDOI2011 second fire-half + + tree problem greedy

Problem:
  a country there are n cities, any two of the n cities are communicating and there is a unique path, the two cities each communication path length zi (zi <= 1000).
  People in this country have a passion beyond the universe to the flame, so the country's most thriving industry is the fire industry. As the government ran out of patience enthusiasm nationals (a large number of fire overhead expenses) but yet do nothing (the presidential campaign to support the national rate), we can only try ways to improve fire fighting capability.
  Now this country funds sufficient to establish a fire on the hub side length s and not more than the path (city at both ends), in order to maximize the utilization of the hub, the distance to all other cities requires that the maximum value of minimum path .
  You appointed to oversee the project, of course you need to know to establish a hub in what position.

Input Format

Comprising n input lines:
the first line, two positive integers n and s, separated by a space. Wherein n is the number of cities, s is the path length of the boundary. In this set of nodes numbered 1,2, ......, n.
  From the second line to the n-th line, each line separated by a space given positive integer 3 illustrates a sequence number and length of the two end points of each edge. For example, "247" represents the length of edges connecting the nodes 2 and 4 to 7.

Output Format

   Output comprising a non-negative integer, i.e. the maximum of all the cities to the selected path, of course, the maximum value of all programs must be the smallest.

Sample input

Sample input [1]
. 5 2
1 2. 5
2. 3 2
2. 4. 4
2. 5. 3
 
[2] Sample input
. 8. 6
1. 3 2
2 2. 3 
. 3. 6. 4
. 4. 3. 5
. 4. 6. 4
. 4. 7 2
. 7. 8. 3 

Sample Output

[1] Sample Output
5

[2] Output Sample
5

prompt

[Data size] and conventions
for 20% of data, n <= 300.
For 50% of the data, n <= 3000.
To 100% of the data, n <= 300000, 1000 is equal to the small side length.

 

solution:

This problem has a clear dichotomy signal 

Then the key is how greedy verified answers

 

Notice: We have

Farthest point from the maximum point of the tree at any point must be the endpoint of the tree (the diameter of the tree to find Method)

Then the path is selected issues 

Painted figure shows on this path a certain diameter of the tree or the maximum distance is not optimal solution

Therefore, we determined BFS twice the diameter of the tree and then select the appropriate binary answer path in diameter (half the answer is bound lower bound on the distance from any point to the diameter of the tree is the length of the diameter)

 

code:

//
#include<bits/stdc++.h>
using namespace std;
int n,ss;
#define maxnn 700000
int las[maxnn],nex[maxnn],en[maxnn],le[maxnn],tot;
int mark[maxnn];
int b[maxnn];
int ccc[maxnn];
int r,l;
void add(int a,int b,int c) {
    en[++tot]=b;
    nex[tot]=las[a];
    las[a]=tot;
    le[tot]=c;
}
queue <int > Q;
int bfs(int v) {
    memset(ccc,0,sizeof(ccc));
    memset(mark,0,sizeof(mark));
    int male=0;
    int ans=0;
    mark[v]=1;
    int lle=0;
    Q.push(v);
    while(Q.size()) {
        int s=Q.front();
        Q.pop();
            for(int i=las[s]; i; i=nex[i]) {
            int u=en[i];
            if(!mark[u]) {
                Q.push(u);
                ccc[u]=ccc[s]+le[i];
                mark[u]=1;
                if(male<ccc[s]+le[i]) {
                    male=max(male,ccc[s]+le[i]);
                    ans=u;
                }
            }
        }
    }
    return ans;
}
void dfs(int s1,int s2,int v,int s)
{
    l=max(l,s);
    for(int i=las[v];i;i=nex[i])
    {
        int u=en[i];
        if(u!=s1&&u!=s2)
        {
            dfs(v,v,u,s+le[i]);
        }
        
    }
}
void ddfs(int fa,int x,int y ,int t ,int s) {
    if(x==y)
    {
        b[0]=t;
        b[t]=s;
        r=s;
        return ;
    }
    for(int i=las[x];i;i=nex[i])
    {
            int v=en[i];
            if(fa!=v)
            {
            ddfs(x,v,y,t+1,s+le[i]);
            if(b[0])
            {
                b[t]=s;
                dfs(fa,en[i],x,0);//直径的前缀和
                return ;
            }
        }
    }
}
bool check(int v)
{
    int i=1,j=1;
    for(i=1;i<=b[0];i++)
    {
        if(b[i]>v) break;
    }
    i--;
    for(j=i;j<=b[0];j++)
    {
        if(b[j]-b[i]>ss) break;
    }
    j--;
    return b[b[0]]-b[j]<=v;
    
}
int main() {
    cin>>n>>ss;
    int x,y,z;
    for(int i=1; i<n; i++) {
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    int ll =bfs(1);
    int rr=bfs(ll);
    ddfs(0,ll,rr,1,0);
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(check(mid)) r=mid-1;
        else
        l=mid+1;
    }
    cout<<l;

}

 

Guess you like

Origin www.cnblogs.com/OIEREDSION/p/11370601.html