码迷,mamicode.com
首页 > 其他好文 > 详细

Columbus’s bargain (hdu 3268 最短路)

时间:2015-08-25 23:48:32      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:columbuss bargain   hdu 3268   最短路   

Columbus’s bargain

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1836    Accepted Submission(s): 467


Problem Description
On the evening of 3 August 1492, Christopher Columbus departed from Palos de la Frontera with a few ships, starting a serious of voyages of finding a new route to India. As you know, just in those voyages, Columbus discovered the America continent which he thought was India.

Because the ships are not large enough and there are seldom harbors in his route, Columbus had to buy food and other necessary things from savages. Gold coins were the most popular currency in the world at that time and savages also accept them. Columbus wanted to buy N kinds of goods from savages, and each kind of goods has a price in gold coins. Columbus brought enough glass beads with him, because he knew that for savages, a glass bead is as valuable as a gold coin. Columbus could buy an item he need only in four ways below:

1.  Pay the price all by gold coins.
2.  Pay by ONE glass bead and some gold coins. In this way, if an item’s price is k gold coins, Columbus could just pay k – 1 gold coins and one glass bead.
3.  Pay by an item which has the same price.
4.  Pay by a cheaper item and some gold coins. 

Columbus found out an interesting thing in the trade rule of savages: For some kinds of goods, when the buyer wanted to buy an item by paying a cheaper item and some gold coins, he didn’t have to pay the price difference, he can pay less. If one could buy an item of kind A by paying a cheaper item of kind B plus some gold coins less than the price difference between B and A, Columbus called that there was a “bargain” between kind B and kind A. To get an item, Columbus didn’t have to spend gold coins as many as its price because he could use glass beads or took full advantages of “bargains”. So Columbus wanted to know, for any kind of goods, at least how many gold coins he had to spend in order to get one – Columbus called it “actual price” of that kind of goods. 

Just for curiosity, Columbus also wanted to know, how many kinds of goods are there whose “actual price” was equal to the sum of “actual price” of other two kinds.
 

Input
There are several test cases. 
The first line in the input is an integer T indicating the number of test cases ( 0 < T <= 10).
For each test case:
The first line contains an integer N, meaning there are N kinds of goods ( 0 < N <= 20). These N kinds are numbered from 1 to N.

Then N lines follow, each contains two integers Q and P, meaning that the price of the goods of kind Q is P. ( 0 <Q <=N, 0 < P <= 30 )
The next line is a integer M( 0 < M <= 20 ), meaning there are M “bargains”. 

Then M lines follow, each contains three integers N1, N2 and R, meaning that you can get an item of kind N2 by paying an item of kind N1 plus R gold coins. It’s guaranteed that the goods of kind N1 is cheaper than the goods of kind N2 and R is none negative and less than the price difference between the goods of kind N2 and kind N1. Please note that R could be zero. 
 

Output
For each test case:
Please output N lines at first. Each line contains two integers n and p, meaning that the “actual price” of the goods of kind n is p gold coins. These N lines should be in the ascending order of kind No. . 

Then output a line containing an integer m, indicating that there are m kinds of goods whose “actual price” is equal to the sum of “actual price” of other two kinds.
 

Sample Input
1 4 1 4 2 9 3 5 4 13 2 1 2 3 3 4 6
 

Sample Output
1 3 2 6 3 4 4 10 1
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:  3265 3264 3262 3269 3263 
 


题意:n个物品,每个物品价值为pi,可以用一个玻璃珠和pi-1个金币换的,也可以由其他便宜的物品加上一定量的金币换得,相同价格的物品可以互换。问每个物品通过这样交换若干次后最少要花的金币数是多少。并且有多少物品的actual price等于其他两个物品actual price之和,注意每个物品如果有多个组合形式也只算作一种。

代码:

#include <iostream>
#include <functional>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;

#define INF 0x3f3f3f3f
#define mod 1000000009
const int maxn = 1005;
const int MAXN = 2005;
const int MAXM = 200010;

typedef pair<int,int> P;

struct Edge
{
    int v,len,next;
}edge[MAXM];

int a[MAXN];
int head[MAXN],dist[MAXN];
int num,n,m;
int vis[MAXN];

void init()
{
    num=0;
    memset(head,-1,sizeof(head));
}

void addedge(int u,int v,int w)
{
    edge[num].v=v;
    edge[num].len=w;
    edge[num].next=head[u];
    head[u]=num++;
}

void Dijkstra()
{
    priority_queue<P,vector<P>,greater<P> >Q;
    memset(dist,INF,sizeof(dist));
    Q.push(P(0,0));
    dist[0]=0;
    while (!Q.empty())
    {
        P p=Q.top();
        Q.pop();
        int u=p.second;
        if (dist[u]<p.first) continue;
        for (int i=head[u];~i;i=edge[i].next)
        {
            int v=edge[i].v;
            if (dist[v]>dist[u]+edge[i].len)
            {
                dist[v]=dist[u]+edge[i].len;
                Q.push(P(dist[v],v));
            }
        }
    }
    for (int i=1;i<=n;i++)
        printf("%d %d\n",i,dist[i]);
    int ans=0;
    memset(vis,0,sizeof(vis));      //每种物品有多种组合方式也只算作一种,用vis来标记
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        {
            if (i==j) continue;
            for (int k=j+1;k<=n;k++)
            {
                if (i==k||j==k) continue;
                if (dist[i]==dist[j]+dist[k]&&!vis[i])
                {
                    ans++;
                    vis[i]=1;
                }
            }
        }
    }
    printf("%d\n",ans);
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
    int i,j,t,u,v,w;
    scanf("%d",&t);
    while (t--)
    {
        init();
        scanf("%d",&n);
        for (i=1;i<=n;i++)
        {
            scanf("%d%d",&u,&a[i]);
            a[i]--;
            addedge(0,u,a[i]);
        }
        for (i=1;i<=n;i++)
        {
            for (j=1;j<=n;j++)
            {
                if (a[i]==a[j])
                    addedge(i,j,0);
            }
        }
        scanf("%d",&m);
        while (m--)
        {
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
        }
        Dijkstra();
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

Columbus’s bargain (hdu 3268 最短路)

标签:columbuss bargain   hdu 3268   最短路   

原文地址:http://blog.csdn.net/u014422052/article/details/47985327

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!