POJ 3013 【需要一点点思维...】【乘法分配率】

题意:

(这题明显感觉自己是英语渣)

给n个点从1到n标号,下面一行是每个点的权,另外给出m条边,下面是每条边的信息,两个端点+权值,边是无向边。你的任务是选出一些边,使这个图变成一棵树。这棵树的花费是这样算的,1号固定为树根,树中每个双亲节点下面的边都有个单价(即边权),然后单价乘上这条边的下面所有的子孙后代的点权和(COPY FROM:http://www.cnblogs.com/scau20110726/archive/2013/05/06/3063401.html)

思路:

题目说每个点都要用上,这时候画个图,想想乘法分配率...

坑点:

这道题的dis默认的inf值要稍大一些...

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int n,m;
int tmp[50005];
const long long inf=199999999999999;
long long dis[50005];
bool vis[50005];
struct edge
{
    int id;
    int mint;
    edge *next;
};
edge edges[100500];
edge *adj[50005];
int ednum;
inline void addEdge(int a,int b,int c)
{
    edge *tmp;
    tmp=&edges[ednum];
    ednum++;
    tmp->id=b;
    tmp->mint=c;
    tmp->next=adj[a];
    adj[a]=tmp;
}
bool SPFA()
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
    {
        dis[i]=inf;
    }
    queue<int>q;
    q.push(1);
    vis[1]=1;
    dis[1]=0;
    while(!q.empty())
    {
        int tmp=q.front();
        q.pop();
        vis[tmp]=0;
        for(edge *p=adj[tmp];p;p=p->next)
        {
            if(p->mint+dis[tmp]<dis[p->id])
            {
                dis[p->id]=p->mint+dis[tmp];
                if(!vis[p->id])
                {
                    q.push(p->id);
                    vis[p->id]=1;
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(dis[i]==inf)
            return 0;
    }
    return 1;
}
long long cal()
{
    long long rel=0;
    for(int i=1;i<=n;i++)
    {
        rel+=((long long )dis[i])*tmp[i];
    }
    return rel;
}
int main()
{
    int t,a,b,c;
    scanf("%d",&t);
    for(int tt=1;tt<=t;tt++)
    {
        ednum=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            adj[i]=NULL;
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&tmp[i]);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            addEdge(a,b,c);
            addEdge(b,a,c);
        }
        if(SPFA())
        {
            printf("%I64d\n",cal());
        }
        else
        {
            printf("No Answer\n");
        }
    }
}
时间: 2024-09-26 20:58:18

POJ 3013 【需要一点点思维...】【乘法分配率】的相关文章

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA)

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意: 圣诞树是由n个节点和e个边构成的,点编号1-n,树根为编号1,选择一些边,使得所有节点构成一棵树,选择边的代价是(子孙的点的重量)×(这条边的价值).求代价最小多少. 分析: 单看每个点被计算过的代价,很明显就是从根到节点的边的价值.所以这是个简单的单源最短路问题. 不过坑点还是很多的. 点的数量高达5w个,用矩阵存不行,只能用边存. 还有路径和结

POJ 3013 Big Christmas Tree(最短Dijkstra+优先级队列优化,SPFA)

POJ 3013 Big Christmas Tree(最短路Dijkstra+优先队列优化,SPFA) ACM 题目地址:POJ 3013 题意: 圣诞树是由n个节点和e个边构成的,点编号1-n.树根为编号1,选择一些边.使得全部节点构成一棵树.选择边的代价是(子孙的点的重量)×(这条边的价值). 求代价最小多少. 分析: 单看每一个点被计算过的代价,非常明显就是从根到节点的边的价值.所以这是个简单的单源最短路问题. 只是坑点还是非常多的. 点的数量高达5w个,用矩阵存不行.仅仅能用边存. 还

POJ 3150 Cellular Automaton(矩阵乘法+二分)

题目链接 题意 : 给出n个数形成环形,一次转化就是将每一个数前后的d个数字的和对m取余,然后作为这个数,问进行k次转化后,数组变成什么. 思路 :下述来自here 首先来看一下Sample里的第一组数据.1 2 2 1 2经过一次变换之后就成了5 5 5 5 4它的原理就是a0 a1 a2 a3 a4->(a4+a0+a1) (a0+a1+a2) (a1+a2+a3) (a2+a3+a4) (a3+a4+a0) 如果用矩阵相乘来描述,那就可以表述为1xN和NxN的矩阵相乘,结果仍为1xN矩阵a

poj 3013 Big Christmas Tree (dij+优先队列优化 求最短路)

模板 题意:给你一个图,1总是为根,每个边有单位价值,每个点有权重. 每条边的价值 = sum(后继节点权重)*边的单位价值. 求树的最小价值,即构成一棵树的n-1条边的最小价值. 算法: 1.因为每个边的价值都要乘以后来访问的节点的权重,而走到后来访问的点必经过这条边. 实际上总价值就是  到每个点的最短路径*这个点的权重. 2.但是这个题 数据量真的太大了,50000个点,50000条边. 写普通的dij算法tle. 必须加优先队列优化- - 据说spfa也能过,但是spfa算法不稳定- -

poj 2406 Power Strings(KMP&amp;思维)

Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 31093   Accepted: 12974 Description Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "

什么是 Java 对象分配率

类似“不可持续的内存分配率”和“你需要维持低的内存分配率”这样的短语看起都像是属于 Java 冠军(Java Champions)的专有词汇.复杂.吓人.充满神秘色彩. 这些词语经常出现,但是如果你深入了解这些概念,它的神秘色彩就烟消云散了.这篇文章将试着揭开上面这些术语的神秘面纱. 什么是内存分配率?我们为什么要关心它? 内存分配率是指单位时间内分配内存的总数量,通常用 MB/sec 表示.不过,如果你乐意,也可以用 PB/year 来表示.这就是全部的内容——没那么神秘,仅仅是指 Java

POJ 3013 Big Christmas Tree【最短路变形,DIjkstra堆优化+spfa算法】

Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 23064   Accepted: 4987 Description Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparing a big neat Christmas tree. The simple structure of t

【POJ】3070 Fibonacci(矩阵乘法)

http://poj.org/problem?id=3070 根据本题算矩阵,用快速幂即可. 裸题 #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> using namespace std; #define rep(i, n) for(int i=0; i<

poj 3013 Big Christmas Tree

Big Christmas Tree 题意:输入v个节点和e条边(0 ≤ v, e ≤ 50000) 的图,第二行输入每个节点的权值,之后e行输入每条边的端点和权值: 问是否能找出一棵树,使得树中的边权乘以该边下面的子孙节点权值之和的sigma总和最小:(树以1为根节点) Sample Input 1 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 (删掉) Sample Output 1210 分析:如果计算最小乘