Buy or Build POJ - 2784

版权声明:欢迎转载!拒绝抄袭. https://blog.csdn.net/qq_36257146/article/details/88559812

其实这道题我没有写对~

我一开始写的是UVa 1151,结果是错的,然后看到有个博主说POJ上有道一毛一样的题目,迅速水过,但是到了UVa就各种WA,心里好奇,一提交POJ竟然AC。。。

好吧(╯▽╰),先贴,等我找找原因为什么错再来改改。

#include <iostream>
#include <algorithm>
#include <vector>
#define ll long long
#define maxn 1101
#define inf  0x3f3f3f3f
using namespace std;

struct Edge
{
    int u,v,w;
    Edge(int i,int j,int k):u(i),v(j),w(k) {}
    Edge() {}
    const bool operator < (const Edge & a)const
    {
        return w<a.w;
    }
};

struct Node
{
    int cost;
    vector<Edge>edges;
};
Node nodes[10];
vector<Edge>e,e1;//在套餐之外的边和已经确定的边
int p[maxn],X[maxn],Y[maxn];//点
int n,q;
ll result;
int choose[8][3] = {{0,0,0},{1,0,0},{0,1,0},{0,0,1},{1,1,0},{1,0,1},{0,1,1},{1,1,1}};//八种选择套餐

int Find(int x)
{
    return p[x] == x ? x: p[x] = Find(p[x]);
}

//首先kruskal
void kruskal()
{
    ll ans = 0;
    sort(e.begin(),e.end());
    for(int i = 1; i<=n; i++) p[i] = i;
    for(int i = 0; i<e.size(); i++)
    {
        int x = Find(e[i].u);
        int y = Find(e[i].v);
        if(x!=y)
        {
            e1.push_back(e[i]);
            ans += e[i].w;
            p[x] = y;
        }
    }

}


int getCost(int i,int j)
{
    return (X[i]-X[j])*(X[i]-X[j]) + (Y[i]-Y[j])*(Y[i]-Y[j]);
}


void solve(int i)
{
    ll ans = 0;
    vector<Edge>temp;
    for(int j = 0; j<q; j++)
    {
        if(i&(1<<j))//套餐j
        {
            Node t = nodes[j];
            ans+=t.cost;
            for(int k = 0; k<t.edges.size(); k++)
            {
                temp.push_back(t.edges[k]);
            }
        }
    }
    //把原来树中的加进去
    for(i = 0; i<e1.size(); i++)
    {
        temp.push_back(e1[i]);
    }
    sort(temp.begin(),temp.end());

    for(i = 1; i<=n; i++) p[i] = i;
    for(int j = 0; j<temp.size(); j++)
    {
        int x = Find(temp[j].u);
        int y = Find(temp[j].v);
        if(x!=y)
        {
            ans+=temp[j].w;
            p[x] = y;
        }
    }
    result = min(result,ans);

//    for(int j = 0;j<edges.size();j++)
//    {
//        cout<<edges[j].u<<"  "<<edges[j].v<<" "<<edges[j].w<<endl;
//    }
//    cout<<"+++++++++++++++++"<<endl;
}


int main()
{
    int T,num,cost,t;
    int a,b;
    int temp[maxn];
    int kase = 0;
    //cin>>T;
    //while(T--)
    //{
       // if(kase++) cout<<endl;
        result = inf;
        e.clear();e1.clear();
        cin>>n>>q;
        for(int i = 0; i<q; i++)
        {
            cin>>num>>nodes[i].cost;
            for(int j = 0; j<num; j++)
            {
                cin>>temp[j];
                //nodes[i].points.push_back(t);
            }
            for(int j = 0;j<num;j++)
            {
                for(int k = j+1;k<num;k++)
                {
                    a = temp[j];b = temp[k];
                    nodes[i].edges.push_back(Edge(a,b,0));
                }
            }
        }

        //点
        for(int i = 1; i<=n; i++)
        {
            cin>>X[i]>>Y[i];
        }
        //点与点之间构成边
        for(int i = 1; i<=n; i++)
        {
            for(int j = i+1; j<=n; j++)
            {
                e.push_back(Edge(i,j,getCost(i,j)));
            }
        }
        kruskal();
        for(int i = 0; i<(1<<q); i++)
        {
            solve(i);
        }
        cout<<result<<endl;
    //}
    return 0;
}
/**
1
7 3
2 4 1 16
3 3 3 6 7
3 9 2 4 5
0 2
4 0
2 0
4 2
1 3
0 5
4 4
**/

猜你喜欢

转载自blog.csdn.net/qq_36257146/article/details/88559812
今日推荐