Minimum Spanning Tree thematic exercises

CH6201 corridor Songkran

Given a tree of N nodes, increasing the number of required edges, this tree is expanded to a complete graph, and the only meet the minimum spanning tree is still the tree. The sum of the edge weights are seeking to increase the minimum number.
Data range: N <= 6000, the edge weights are non-negative integers.



The basic idea: the N-1 edges by weight in ascending order, one each side of the tree scanning is performed Kruskal (a plus operation at each step).

Set to the current scan edge (x, y, V), if x, y is not a collection, the merge Sx, Sy, expense (+ V. 1) (| to Sx | | Sy | -1). This will ensure that each set is a complete graph, (v + 1) is to ensure the original tree is a minimum spanning tree of FIG.

Time complexity (n logn).

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;

co int N=6001;
struct rec {int x,y,z;}edge[N];
int fa[N],s[N],n;
ll ans;
bool operator<(co rec&a,co rec&b) {return a.z<b.z;}
int get(int x) {return fa[x]==x?x:fa[x]=get(fa[x]);}
int main(){
    for(int T=read<int>();T--;){
        read(n);
        for(int i=1;i<n;++i) read(edge[i].x),read(edge[i].y),read(edge[i].z);
        sort(edge+1,edge+n);
        for(int i=1;i<=n;++i) fa[i]=i,s[i]=1;
        ans=0;
        for(int i=1;i<n;++i){
            int x=get(edge[i].x),y=get(edge[i].y);
            if(x==y) continue;
            ans+=(ll)(edge[i].z+1)*(s[x]*s[y]-1);
            fa[x]=y,s[y]+=s[x];
        }
        printf("%lld\n",ans);
    }
    return 0;
}

POJ1639 Picnic Planning

Go accepoc blog.

There are n brothers picnic destination for the Park. Each person can choose to go directly to the Park, you can choose to go to other people, and with him traveled to Park.
Parking space for everyone to have no limit, but can not exceed the number of parking Park k. I asked the shortest route of all.



Assuming that the number of parking Park is no limit, then it is a question of the minimum spanning tree.
But the number of parking restrictions Park this question can not exceed k, the Park is seen as the root note of V0, then that is its degree can not exceed k.
K obtained in step a spanning tree of the limits:

  1. Ignoring the root do a kruskal, obtained at this time is a forest that contains m a minimum spanning tree.
  2. For each of a minimum spanning tree, select the nearest point from the root node, the root node is connected to one side, then to obtain a minimum spanning tree of degree m.
  3. M + 1 obtained by the m degree of the spanning tree spanning:
    (1) dp pretreated with the current spanning tree on a path from the point V0 V0 i is not associated with the maximum weight side, denoted as dp [i ] .d, end points of the edge referred to as dp [i] .u and dp [i] .v.
    (2) For one side of the spanning tree is not <V0, v>, spanning tree, if the edge is added, it must get a ring.
    At this point we delete the maximum weight ring side, i.e., dp [v] (1) obtained in the pretreatment, to obtain an m + 1-degree spanning tree.
    . (3) (2) each enumeration v, denoted minnum = min {(V0, v ) - dist [v] .d}, so that the point obtained minnum v is the minimum value of the selected point. Connecting V0, v, deleting dp [v].
  4. Repeat step 3 until k limits in a spanning tree. This question does not exceed the required degree k, so in a certain step, minnum> = 0, you can output the answer.

The meaning of minnum:
minnum in the process to give m + 1 m from the level of the spanning tree spanning tree, to select a point v (V0 connection, v, deleting DP [v]) the maximum benefit can be obtained, i.e., spanning tree the value can be reduced up much.
minnum negative, it indicates a decrease can select point v spanning tree value, then the smallest point minnum is that we can reduce the value of the spanning tree up to a point, this time we will choose it.
If minnum> = 0, m + 1 of the instructions to get the spanning tree will not get any benefit, would not continue, the answer can be output directly.

Limit for the minimum degree spanning tree details Reference 2004 National Team Wang Ting papers.

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;

co int N=40,INF=0x3f3f3f3f;
struct E{
    int x,y,z;
    bool operator<(co E&w)co {return z<w.z;}
}f[N];
int n,k,tot,ans,a[N][N],fa[N],d[N],v[N];
map<string,int> m;
vector<E> e;
bool b[N][N];
int get(int x) {return fa[x]==x?x:fa[x]=get(fa[x]);}
void dfs(int x,int fa){
    for(int i=2;i<=tot;++i){
        if(i==fa||!b[x][i]) continue;
        if(f[i].z==-1){
            if(f[x].z>a[x][i]) f[i]=f[x];
            else f[i].x=x,f[i].y=i,f[i].z=a[x][i];
        }
        dfs(i,x);
    }
}
int main(){
    read(n);
    memset(a,0x3f,sizeof a);
    memset(d,0x3f,sizeof d);
    m["Park"]=tot=1;
    for(int i=0;i<N;++i) fa[i]=i;
    for(int i=1;i<=n;++i){
        E w;
        string s1,s2;
        cin>>s1>>s2>>w.z;
        w.x=m[s1]?m[s1]:(m[s1]=++tot);
        w.y=m[s2]?m[s2]:(m[s2]=++tot);
        e.push_back(w);
        a[w.x][w.y]=a[w.y][w.x]=min(a[w.x][w.y],w.z);
    }
    cin>>k;
    sort(e.begin(),e.end());
    for(unsigned i=0;i<e.size();++i){
        if(e[i].x==1||e[i].y==1) continue;
        int rtx=get(e[i].x),rty=get(e[i].y);
        if(rtx!=rty){
            fa[rtx]=rty;
            b[e[i].x][e[i].y]=b[e[i].y][e[i].x]=1;
            ans+=e[i].z;
        }
    }
    for(int i=2;i<=tot;++i)
        if(a[1][i]!=INF){
            int rt=get(i);
            if(d[rt]>a[1][i]) d[rt]=a[1][v[rt]=i]; // 每颗最小生成树中距离根节点最近的点与根节点的距离
        }
    for(int i=1;i<=tot;++i)
        if(d[i]!=INF){
            --k;
            b[1][v[i]]=b[v[i]][1]=1;
            ans+=a[1][v[i]];
        }
    while(k--){
        memset(f,-1,sizeof f);
        f[1].z=-INF;
        for(int i=2;i<=tot;++i)
            if(b[1][i]) f[i].z=-INF;
        dfs(1,-1); // dp预处理
        int o,w=-INF;
        for(int i=2;i<=tot;++i)
            if(w<f[i].z-a[1][i])
                w=f[i].z-a[1][o=i];
        if(w<=0) break;
        b[1][o]=b[o][1]=1;
        b[f[o].x][f[o].y]=b[f[o].y][f[o].x]=0;
        ans-=w;
    }
    printf("Total miles driven: %d\n",ans);
    return 0;
}

POJ2728 Desert King

There are n villages, villages in different coordinate and elevation, now the water supply to all villages, as long as there is a road between two villages to the construction of water pipes distance Euclidean distance between the coordinates, altitude difference between the cost of , so that the program now requires a minimum ratio of the distance costs.



Obviously, this problem is to require a minimum ratio spanning tree. 01 fractional programming problem, we can solve half.
Since then POJ bombed (502 Bad Gateway), so this code will look at the title on the line.

//Author:XuHt
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1006, INF = 0x3f3f3f3f;
const double eps = 1e-6;
int n;
struct P {
    int x, y, z;
} p[N];
double a[N][N], b[N][N], c[N][N], d[N];
bool v[N];

inline double s(int i, int j) {
    return sqrt((p[i].x - p[j].x) * (p[i].x - p[j].x) + (p[i].y - p[j].y) * (p[i].y - p[j].y));
}

double work(double k) {
    for (int i = 1; i <= n; i++)
        for (int j = i; j <= n; j++)
            if (i == j) c[i][j] = INF;
            else c[i][j] = c[j][i] = a[i][j] - k * b[i][j];
    memset(v, 0, sizeof(v));
    for (int i = 1; i <= n; i++) d[i] = INF;
    d[1] = 0;
    double ans = 0;
    while (1) {
        int x = 0;
        for (int i = 1; i <= n; i++)
            if (!v[i] && (!x || d[x] > d[i])) x = i;
        if (!x) break;
        v[x] = 1;
        ans += d[x];
        for (int i = 1; i <= n; i++) d[i] = min(d[i], c[x][i]);
    }
    return ans;
}

void Desert_King() {
    for (int i = 1; i <= n; i++)
        scanf("%d %d %d", &p[i].x, &p[i].y, &p[i].z);
    double num = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) {
            num += (a[i][j] = a[j][i] = abs(p[i].z - p[j].z));
            b[i][j] = b[j][i] = s(i, j);
        }
    double l = 0, r = num;
    while (l + eps <= r) {
        double mid = (l + r) / 2;
        if (work(mid) >= 0) l = mid;
        else r = mid;
    }
    printf("%.3f\n", l);
}

int main() {
    while (cin >> n && n) Desert_King();
    return 0;
}

CH6202 Dark Castle

Subject to the requirement source shortest path remaining point d [i], and seeking the tree path s [i] is equal to d [i] spanning tree
so that first find the shortest path d [i], and record d [i [is shortest path attributes which point to V;
then sorted according to size of length, in order to avoid double counting ,, finally satisfy d [x] = d [y ] + w [i] [j] to generate a point of a point among the tree plus
find answers to multiplication according to the principle of

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;

co int N=1001;
int n,m,a[N][N],d[N];
bool v[N];
int main(){
    read(n),read(m);
    memset(a,0x3f,sizeof a);
    for(int i=1;i<=n;++i) a[i][i]=0;
    for(int i=1,x,y,z;i<=m;++i){
        read(x),read(y),read(z);
        a[x][y]=a[y][x]=min(a[x][y],z);
    }
    memset(d,0x3f,sizeof d);
    d[1]=0;
    for(int i=1;i<n;++i){
        int t=0;
        for(int j=1;j<=n;++j)
            if(!v[j]&&(!t||d[j]<d[t])) t=j;
        v[t]=1;
        for(int j=1;j<=n;++j)
            d[j]=min(d[j],d[t]+a[t][j]);
    }
    memset(v,0,sizeof v);
    v[1]=1;
    int ans=1;
    for(int i=1;i<=n;++i){
        int t=0,k=0;
        for(int j=2;j<=n;++j)
            if(!v[j]&&(!t||d[j]<d[t])) t=j;
        for(int j=1;j<=n;++j)
            if(v[j]&&d[j]+a[j][t]==d[t]) ++k;
        v[t]=1;
        ans=(ll)ans*k%0x7fffffff;
    }
    printf("%d\n",ans);
    return 0;
}

POJ2349 Arctic Network

Description

The Department of National Defence (DND) wishes to connect several northern outposts by a wireless network. Two different communication technologies are to be used in establishing the network: every outpost will have a radio transceiver and some outposts will in addition have a satellite channel.
Any two outposts with a satellite channel can communicate via the satellite, regardless of their location. Otherwise, two outposts can communicate by radio only if the distance between them does not exceed D, which depends of the power of the transceivers. Higher power yields higher D but costs more. Due to purchasing and maintenance considerations, the transceivers at the outposts must be identical; that is, the value of D is the same for every pair of outposts.

Your job is to determine the minimum D required for the transceivers. There must be at least one communication path (direct or indirect) between every pair of outposts.

Input

The first line of input contains N, the number of test cases. The first line of each test case contains 1 <= S <= 100, the number of satellite channels, and S < P <= 500, the number of outposts. P lines follow, giving the (x,y) coordinates of each outpost in km (coordinates are integers between 0 and 10,000).



Direct minimum spanning tree. Satellite communication for communicating the last remaining block.

#include<iostream>
#include<cmath>
#include<algorithm>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;

co int N=501;
pair<int,int> p[N];
struct E{
    int x,y,z;
    il bool operator<(co E&w)co{
        return z<w.z;
    }
}e[N*N];
int n,m,fa[N];

il int dis(int x,int y){
    return (p[x].first-p[y].first)*(p[x].first-p[y].first)+(p[x].second-p[y].second)*(p[x].second-p[y].second);
}
int get(int x) {return fa[x]==x?x:fa[x]=get(fa[x]);}
void Arctic_Network(){
    read(n),read(m);
    for(int i=1;i<=m;++i){
        fa[i]=i,read(p[i].first),read(p[i].second);
    }
    int tot=0;
    for(int i=1;i<=m;++i)
        for(int j=i+1;j<=m;++j)
             e[++tot].x=i,e[tot].y=j,e[tot].z=dis(i,j);
    sort(e+1,e+tot+1);
    int cnt=m-n;
    for(int i=1;i<=tot;++i){
        int x=get(e[i].x),y=get(e[i].y);
        if(x==y) continue;
        fa[x]=y;
        if(!--cnt) return printf("%.2lf\n",sqrt((double)e[i].z)),void();
    }
}
int main(){
    for(int t=read<int>();t--;) Arctic_Network();
    return 0;
}

Guess you like

Origin www.cnblogs.com/autoint/p/10914438.html
Recommended