UV 1151-buy or build poj 2784 buy or build (Minimum Spanning Tree)

Source: Internet
Author: User

It is also a simple Minimum Spanning Tree Algorithm.

However, some new things need to be added, which requires a deep understanding of the Minimum Spanning Tree Algorithm and the use of the query set.

The solution to the problem is also complicated.

#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;const int maxn = 1005;struct point{    int x;    int y;}pp[maxn];struct edge{    int s;    int e;    int dist;}l[maxn*maxn];int n,q,m;int p[maxn];vector<int> g[10];int c[10];int distance_(point a,point b){    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}int cmp(edge a,edge b){    return a.dist < b.dist;}int find_(int x){    return p[x]==x?x:p[x]=find_(p[x]);}bool merge_(int a,int b){    int x=find_(a);    int y=find_(b);    if(x==y) return false;    p[x]=y;    return true;}int kruskal(){    int ans=0;    int num=0;    for(int i=0;i<m&&num<n-1;i++)    {        if(merge_(l[i].s,l[i].e))        {            num++;            ans+=l[i].dist;        }    }    return ans;}void solve(){    for(int i=0;i<=n;i++) p[i]=i;    int ans = kruskal();    for(int s=1;s<(1<<q);s++)    {        int cost=0;        for(int tt=0;tt<=n;tt++) p[tt]=tt;        for(int j=0;j<q;j++)        {            if(!((s>>j)&1)) continue;            cost+=c[j];            for(int k=0;k<g[j].size();k++)            {                merge_(g[j][k],g[j][0]);            }        }        ans=min(ans,cost+kruskal());    }    printf("%d\n",ans);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&q);        for(int i=0;i<10;i++) g[i].clear();        for(int i=0;i<q;i++)        {            int cnt;            scanf("%d%d",&cnt,&c[i]);            int a;            for(int j=0;j<cnt;j++)            {                scanf("%d",&a);                g[i].push_back(a);            }        }        for(int i=1;i<=n;i++)        {            scanf("%d%d",&pp[i].x,&pp[i].y);        }        m=0;        for(int i=1;i<=n;i++)        {            for(int j=i+1;j<=n;j++)            {                l[m].s=i;                l[m].e=j;                l[m++].dist=distance_(pp[i],pp[j]);            }        }        sort(l,l+m,cmp);        solve();        if(t) printf("\n");    }    return 0;}

The subset enumeration algorithm is required for the given solutions.

In the preceding solution, the binary help subset enumeration method is used, which is only applicable to the subset enumeration algorithm with small set elements.

The above method uses a struct to represent the edge, without opening so many arrays. I think struct can make the code more readable.


UV 1151-buy or build poj 2784 buy or build (Minimum Spanning Tree)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.