POJ diameter and the center of gravity of the tree

Unrooted tree :( diameter) up to the longest path between two trees, dfs to twice, the first time that dfs Optionally u, find the point farthest from it s, then again from point s dfs, find the point farthest from s t, a path between the diameter of the tree is st. Proof: <http://www.cnblogs.com/wuyiqi/archive/2012/04/08/2437424.html>

Bare tree diameter questions poj2631

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<iostream>
#include<vector>
typedef long long ll;
using namespace std;
const int maxn=10005;
ll d[maxn];
struct KSD
{
    int v,len,next;
}g[maxn];
int vis[maxn];
int head[maxn],cnt;
void add(int u,int v,int len){
    g[++cnt].v=v;
    g[cnt].next=head[u];
    g[cnt].len=len;
    head[u]=cnt;
}
void dfs(int x)
{
    vis[x]=1;
    int i,v;
    for(i=head[x];i;i=g[i].next)
    {
        v=g[i].v;
        if(vis[v])continue;
        d[v]+=d[x]+g[i].len;
        dfs(v);
    }
    return ;
}
int main(){
    int a,b,c;int n=0;
    while(scanf("%d%d%d",&a,&b,&c)!=EOF){

        n=max(a,max(b,n));
        add(a,b,c);
        add(b,a,c);

    }
        d[1]=0;
        dfs(1);
        int m;
        ll s=0;
        for(int i=1;i<=n;i++){
            vis[i]=0;
            if(d[i]>s){
                m=i;
                s=d[i];
            }
            d[i]=0;
        }
        dfs(m);
        ll ans=0;
        for(int i=1;i<=n;i++)
            years = max (years of [i]); 
    printf ( "% lld \ n", year); 
}

poj1985 Cow Marathon seeking tree diameter bare title

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=200005;
int n,m;
struct P{
    int v,len,next;
}g[maxn];

int head[maxn],d[maxn],vis[maxn];
int cnt=0;
void add(int u,int v,int len){
    g[++cnt].v=v;
    g[cnt].next=head[u];
    g[cnt].len=len;
    head[u]=cnt;
}
void dfs(int x)
{
    vis[x]=1;
    int i,v;
    for(i=head[x];i;i=g[i].next)
    {
        v=g[i].v;
        if(vis[v])continue;
        d[v]+=d[x]+g[i].len;
        dfs(v);
    }
    return ;
}
int main(){
    scanf("%d%d",&n,&m);
    int sum=0;
    for(int i=1;i<=n-1;i++){
        int x,y,z;
        char c;
        scanf("%d%d%d %c",&x,&y,&z,&c);
      //  cout<<c<<endl;
        add(x,y,z);
        add(y,x,z);
       // sum+=z;
    }
   // sum=sum*2;
        d[1]=0;
        dfs(1);
        int m;
        int s=0;
        for(int i=1;i<=n;i++){
            vis[i]=0;
            if(d[i]>s){
                m=i;
                s=d[i];
            }
            d[i]=0;
        }
        dfs(m);
        int ans=0;
        for(int i=1;i<=n;i++)
            ans=max(ans,d[i]);
      //  cout<<sum<<" "<<ans<<endl;
        printf("%d\n",ans);
}

poj3310 Caterpillar

Give you an undirected graph, you ask if this map is a Caterpillar, Caterpillar must be satisfied is a connected graph, acyclic, cutting a path exists, all the points in FIG Minimum distance of points on the path 1 or 0

FIG change is easy to know a tree, first determines whether the link disjoint-set, first find the diameter, then the diameter is determined from the distance of all points

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=605;
int fa[maxn],head[maxn],d[maxn],ans[maxn],vis[maxn];
struct P{
    int v,len,next;
}g[maxn*2];
int  mp[maxn][maxn];
int fi(int x){
    if(fa[x]==x)
        return x;
    return fa[x]=fi(fa[x]);
}
int cnt=0;
void add(int u,int v){
    g[++cnt].v=v;
    g[cnt].next=head[u];
    head[u]=cnt;
}
void dfs(int x)
{
    vis[x]=1;
    int i,v;
    for(i=head[x];i;i=g[i].next)
    {
        v=g[i].v;
        if(vis[v])continue;
        d[v]+=d[x]+1;
        dfs(v);
    }
    return ;
}
int n,m,p,q,k=0;
bool DFS(int z){
    if(z==q){
        ans[z]=1;
        return true;
    }
    vis[z]=1;
    for(int i=head[z];i;i=g[i].next){
        int v=g[i].v;
        if(vis[v])
            continue;
        if(DFS(v)){
            ans[v]=1;
            return true;
        }
    }
    return false;
}
int main(){
    int cas=0;
    while(scanf("%d",&n)&&n!=0){
        for(int i=1;i<=n;i++){
            d[i]=vis[i]=ans[i]=head[i]=0;
            fa[i]=i;
            for(int j=1;j<=n;j++)
                mp[i][j]=0;
        }
        scanf("%d",&m);
        bool f=1;
        if(m!=n-1)
            f=0;
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            mp[x][y]=mp[y][x]=1;
            x=fi(x);y=fi(y);
            if(x==y)
                f=0;
            fa[x]=y;
            add(x,y);
            add(y,x);
        }
        for(int i=1;i<=n;i++)
        if(fi(i)!=fi(1)){
            f=0;
            break;
        }
        if(f==0){
            printf("Graph %d is not a caterpillar.\n",++cas);
            continue;
        }
        dfs(1);
        int s=0;
        for(int i=1;i<=n;i++){
            vis[i]=0;
            if(d[i]>s){
                p=i;
                s=d[i];
            }
            d[i]=0;
        }

        dfs(p);
        s=0;
        for(int i=1;i<=n;i++){
            vis[i]=0;
            if(d[i]>s){
                q=i;
                s=d[i];
            }
            d[i]=0;
        }

        DFS(p);
        for(int i=1;i<=n;i++){
            int j=0;
            if(ans[i]==0){
                for(j=1;j<=n;j++)
                if(ans[j]==1){
                    if(mp[i][j]==1)
                        break;
                }
                if(j>n){
                    f=0;
                    break;
                }
            }

        }
        if(f==0){
              printf("Graph %d is not a caterpillar.\n",++cas);
        }
        else   printf("Graph %d is a caterpillar.\n",++cas);

    }
}

poj1849 Two

Snow covers the streets of the town, two snow machines from the same city, requires that all the streets have to shovel snow are complete, any one can shovel snow machine in any street, the last two cars can be parked in any one ask at least two cars length motion

Some roads may pass through once, but some streets need to go through twice, that is the longest distance to find a car on a trip, easy to know which path is the diameter, so the answer is the length of all sides of the diameter * 2-

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=200005;
int n,m;
struct P{
    int v,len,next;
}g[maxn];

int head[maxn],d[maxn],vis[maxn];
int cnt=0;
void add(int u,int v,int len){
    g[++cnt].v=v;
    g[cnt].next=head[u];
    g[cnt].len=len;
    head[u]=cnt;
}
void dfs(int x)
{
    vis[x]=1;
    int i,v;
    for(i=head[x];i;i=g[i].next)
    {
        v=g[i].v;
        if(vis[v])continue;
        d[v]+=d[x]+g[i].len;
        dfs(v);
    }
    return ;
}
int main(){
    scanf("%d%d",&n,&m);
    int sum=0;
    for(int i=1;i<=n-1;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
        sum+=z;
    }
    sum=sum*2;
        d[1]=0;
        dfs(1);
        int m;
        int s=0;
        for(int i=1;i<=n;i++){
            vis[i]=0;
            if(d[i]>s){
                m=i;
                s=d[i];
            }
            d[i]=0;
        }
        dfs(m);
        int ans=0;
        for(int i=1;i<=n;i++)
            ans=max(ans,d[i]);
      //  cout<<sum<<" "<<ans<<endl;
        printf("%d\n",sum-ans);
}

poj3099 Go Go Gorelians

Give you a map, known distance between every two 1, ask you to find the most distant point from a minimum point, that is found in diameter, if the point on the diameter is odd, for the middle, If it is even, compared with the middle two, pay attention to the input of the distance is to make our contribution

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn=10005;
int vis[maxn],head[maxn],cnt,v0[maxn];
struct P{
    int v,next;
  //  double len;
}g[maxn];
struct Q{
    int i,x,y,z;
}p[maxn];
int d[maxn],ans[maxn];
//int sum=0;
void add(int u,int v){
    g[++cnt].v=v;
   // g[cnt].len=len;
    g[cnt].next=head[u];
    head[u]=cnt;
}
int ma;  int n;

void dfs(int x)
{
    vis[x]=1;
    int i,v;
    for(i=head[x];i;i=g[i].next)
    {
        v=g[i].v;
        if(vis[v])continue;
        d[v]+=d[x]+1;
        dfs(v);
    }
    return ;
}
int q;
int l;
bool DFS(int z){
    if(z==q){
        return true;
    }
    vis[z]=1;
    for(int i=head[z];i;i=g[i].next){
        int v=g[i].v;
        if(vis[v])
            continue;
        if(DFS(v)){
            ans[++l]=v;
            return true;
        }
    }
    return false;
}
int main(){

    int c=0;
    while(scanf("%d",&n)&&n!=0){
        l=0;
        ma=1e7;
        for(int i=1;i<=1000;i++)
          vis[i]=head[i]=ans[i]=d[i]=0;
        c=0;
        cnt=0;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d%d",&p[i].i,&p[i].x,&p[i].y,&p[i].z);
            v0[++c]=p[i].i;
        }
        for(int i=2;i<=n;i++){
            int s=1e9;
            int t;
            for(int j=1;j<i;j++){
                int o=(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y)+(p[i].z-p[j].z)*(p[i].z-p[j].z);
                if(o<s){
                    s=o;
                    t=p[j].i;
                }
            }
            add(t,p[i].i);
            add(p[i].i,t);
       
        }
        dfs(v0[1]);
        int c;
        int s=0;
        for(int i=1;i<=n;i++){
            int k=v0[i];
            vis[k]=0;
            if(d[k]>s){
                c=k;
                s=d[k];
            }
            d[k]=0;
        }

        dfs(c);
        s=0;
        for(int i=1;i<=n;i++){
            int k=v0[i];
            vis[k]=0;
            if(d[k]>s){
                q=k;
                s=d[k];
            }
            d[k]=0;
        }

        DFS(c);
       years [++ i] = c; 
     if (l% 2 == 0) { 
        cout << min (years [l / 2 + 1], years [l / 2]) << "" << max (years [l / 2 + 1], years [ l / 2]) << endl; 
     } 
     Else printf ( "% d \ n", years [l / 2 + 1]); 
    } 
}

  

The center of gravity of the tree: if there is a node, all of its sub-tree nodes largest subtree minimum, the center of gravity of the tree node; optionally one point as a root, a DFS, recording the number of children of a node, satisfying max (n-son [u] -1, sou [v]) to take the center of gravity is the smallest tree node u (v u of the child node);

poj3107 Goldfather

The center of gravity of bare tree title

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100005;
int cnt,d[maxn],vis[maxn],head[maxn],ans[maxn];
struct P{
    int v,next;
}g[maxn];
void add(int u,int v){
    g[++cnt].v=v;
    g[cnt].next=head[u];
    head[u]=cnt;
}
int ma=1e9;
int n;
void dfs(int u){
    int sum=0;
    d[u]=1;
    vis[u]=1;
    for(int i=head[u];i;i=g[i].next){
        int v=g[i].v;
        if(vis[v])
            continue;
        dfs(v);
        d[u]+=d[v];
        if(d[v]>=ans[u])
            ans[u]=d[v];
    }
    if(n-d[u]>ans[u])
    ans[u]=n-d[u];
    if(ma>ans[u])
    ma=ans[u];
}
int main(){
        cnt=0;

        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            head[i]=d[i]=vis[i]=0;
        }
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        dfs(1);
        for(int i=1;i<=n;i++){
            if(ans[i]==ma)
            printf("%d ",i);
        }
        printf("\n");
}

poj1655 Banlancing Act

Seeking the center of gravity of the tree, the lowest output lexicographically

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100005;
int cnt,d[maxn],vis[maxn],head[maxn];
struct P{
    int v,next;
}g[maxn];
void add(int u,int v){
    g[++cnt].v=v;
    g[cnt].next=head[u];
    head[u]=cnt;
}
int ans1,ans2;
int n;
void dfs(int u){
    int sum=0;
    d[u]=1;
    vis[u]=1;
    for(int i=head[u];i;i=g[i].next){
        int v=g[i].v;
        if(vis[v])
            continue;
        dfs(v);
        d[u]+=d[v];
        sum=max(sum,d[v]);
    }
    sum=max(sum,n-d[u]);
    if((sum<ans2)||(sum==ans2&&u<ans1)){
        ans1=u;
        ans2=sum;
    }

}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        cnt=0;
        ans1=1e8;
        ans2=1e8;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            head[i]=d[i]=vis[i]=0;
        }
        for(int i=1;i<n;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        dfs(1);
        printf("%d %d\n",ans1,ans2);
    }
}

  

 

Guess you like

Origin www.cnblogs.com/dlutjwh/p/10987787.html