1924 - 圣诞树

通过次数

0

提交次数

0

时间限制 : 1 秒 内存限制 : 128 MB

KFC为了迎接圣诞节的到来,员工们打算准备一个大大的圣诞树。圣诞树的结构示意图如下图所示:

这颗圣诞树可以用一些结点和边来表示。结点的编号为1至n。树根的结点总是编号为1的结点。在树中每个结点有自己的重量。这些重量可以看作是互不相同的。因此每条边也可看作是不一样的,即各边的的单价也就不一样了。一条边的价格是它的所有子结点的重量总和×该边的单价。
员工们想花费最少的钱来准备这棵圣诞树。所有结点都是要被用进的。现在他们想请你帮忙来解决这个问题。

题目输入

第一行包含两个整数v和e(1 < = v,e < = 50000),分别表示节点和边的数目。紧接下面一行包含v个正整数,表示编号1到n的结点重量,再下面e行,每一行三个正整数xi,yi,vi,表示边(xi,yi)的单价为vi。(所有数据都不超过2^16)

题目输出

输出一个整数表示准备这个圣诞树的可能的最小价格。如果没有办法将所有结点用进,输出“No Answer”。

输入/输出样例

输入格式

7 7
200 10 20 30 40 50 60
1 2 1
2 3 3
2 4 2
3 5 4
3 7 2
3 6 3
1 5 9

输出格式

1210

C++解答

/*所求答案是 西格玛(price[i]*西格玛(i的子孙的weight)),可以变换为 西格玛(weight[i]*dist[i]).price 是边的单价,dist是点到根的最短路。weight是点的重量。
因为对于每个点,他前面的边在算价钱的时候都要算到他,所以求最短路 使答案最小。
一个点无法到达时,输出no answer。
数据超大,dijkstra+heap 2.7秒
*/
#include<stdio.h>
#include<string.h>

const int N = 50008;
const long long INF = 1111111;

struct HEAP
{
    long long data;
    int num;
};

struct NODE
{
    long long data;
    int num;
    int next;
};

struct DIJ
{
    long long data;
    int next,last; //qian,hou;
    int vis;
};

HEAP heap[N*2];
NODE list[N*2];
DIJ dis[N*2];
long long w[N*2];
int hash[N*2];
int e,v;
int hsize,next;

void csh()
{
    int i;
    memset(w,0,sizeof(w));
    memset(hash,0,sizeof(hash));
    next = hsize = 0;
    for(i=0;i<v;i++)
    {
        dis[i].data = INF;
        dis[i].next = -1;
        dis[i].vis = 0;
    }
}

void insert(int x,int y,long long p)
{
    list[next].data = p;
    list[next].next = -1;
    list[next].num = y;
    next++;
    if(dis[x].next == -1)
        dis[x].next = next - 1;
    else
        list[dis[x].last].next = next - 1;
    dis[x].last = next - 1;
}

void swap(int x,int y)
{
    struct temp
    { long long data; int num; }tmp;

    tmp.data = heap[x].data;
    tmp.num = heap[x].num;
    heap[x].data = heap[y].data;
    heap[x].num = heap[y].num;
    heap[y].data = tmp.data;
    heap[y].num = tmp.num;
}

void sift_up(int k)
{
    while(k > 0 && heap[(k-1)/2].data > heap[k].data)
    {
        hash[heap[k].num] = (k-1) / 2;
        hash[heap[(k-1)/2].num] = k;
        swap(k,(k-1)/2);
        k = (k-1) / 2;
    }
}

void sift_down(int k)
{
    int flag = 0;
    while(k < hsize && !flag)
    {
        int l = k*2 + 1;
        int r = k*2 + 2;
        int t = -1;
        flag = 1;
        if(r < hsize)
        {    if(heap[l].data <= heap[r].data)
                t = l;
            else
                t = r;
        }
        else if(l < hsize)
            t = l;
        if(t != -1 && (heap[t].data < heap[k].data))
        {
            hash[heap[k].num] = t;
            hash[heap[t].num] = k;
            swap(k,t);
            k = t;
            flag = 0;
        }
    }
}

void dijkstra_heap(int s,int en)
{
    int i,mark,tmp,k,j;
    long long min,d;
    dis[s].data = 0;
    for(i=0;i<en;i++)
    {
        heap[hsize].data = dis[i].data;
        heap[hsize].num = i;
        hsize++;
        hash[i] = hsize-1;
        sift_up(hsize-1);
    }
    
    for(i=0;i<en-1;i++)
    {
        min = heap[0].data;
        mark = heap[0].num;
        if(min == INF) return ;
        dis[mark].vis = 1;
        tmp = heap[hsize-1].num;
        hash[tmp] = 0;
        hash[mark] = hsize - 1;
        swap(0,hsize - 1);
        hsize--;
        sift_up(hash[tmp]);
        sift_down(hash[tmp]);
        for(j=dis[mark].next;j!=-1;j=list[j].next)
        {
            k = list[j].num;
            d = dis[mark].data + list[j].data;
            if(d < dis[k].data)
            {
                dis[k].data = d;
                heap[hash[k]].data = d;
                sift_up(hash[k]);
            }
        }
    }
}

int main()
{

	//freopen("Christmas.in", "r", stdin);
	//freopen("Christmas.out", "w", stdout);
    int i,j,x,y,t,flag;
    long long sum,p;

 //   scanf("%d",&t);
  //  while(t--)
  //  {
        scanf("%d%d",&v,&e);
        csh();
        for(i=0;i<v;i++)
            scanf("%lld",&w[i]);
        for(i=0;i<e;i++)
        {
            scanf("%d%d%lld",&x,&y,&p);
            x--;y--;
            if(x != y)
            {
                insert(x,y,p);
                insert(y,x,p);
            }
        }
        dijkstra_heap(0,v);
        flag = sum = 0;
        for(i=0;i<v;i++)
        {    
            if(dis[i].data == INF)
            {    flag = 1; break;    }
            sum += w[i] * dis[i].data;
        }
        if(flag)
            printf("No Answer\n");
        else
            printf("%lld\n",sum);
 //   }
    return 0;
}