zoukankan      html  css  js  c++  java
  • Columbus’s bargain (hdu3268 最短路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3268

    题意:有以下交换规则

    1.用玻璃球抵掉1块钱(玻璃球有无数个  so 都可以-1)

    2.等价的货物可以两两交换

    3.可以用价格低的+相应的差价 交换到价格高的

    给你n个商品的价格 

    再给m行满足条件3的

     问:最少买这n件商品的钱分别是多少,还有 有多少种商品价格 可以等于另两种相加价格

    题解:用最短路 

    #include<bits/stdc++.h>
    using namespace std;
    int dis[30];
    typedef pair<int,int>pai;
    vector<pai>ve[30];
    int n;
    void dij()
    {
        int i;
        for(i=1;i<=n;i++)dis[i]=0x3f3f3f3f;
        dis[0]=0;
        queue<int>qu;
        qu.push(0);
        while(!qu.empty())
        {
            int f=qu.front();
            qu.pop();
            for(int j=0;j<ve[f].size();j++)
            {
                if(dis[f]+ve[f][j].second<dis[ve[f][j].first])
                {
                    dis[ve[f][j].first]=dis[f]+ve[f][j].second;
                    qu.push(ve[f][j].first);//这里不小心把dis puah进去了
                }
            }
        }
    }
    int main()
    {
        int i,j,m,t;
        cin>>t;
        while(t--)
        {
            cin>>n;
            int q,p;
            int flag[30];
            memset(flag,0,sizeof(flag));
            for(i=0;i<=30;i++)ve[i].clear();//刚开始没有把ve【0】清空
            for(i=1;i<=n;i++)
            {
                cin>>q>>p;
                flag[q]=p;
                for(j=1;j<=n;j++)
                {
                    if((j!=q)&&(flag[j]==p))
                    {
                        ve[j].push_back(pai(q,0));//若有两个商品价格一样则可以连一条0的边
                                                  //因为 若可以用更低的价格换j ,j和q价格一样 那么q也可以用j的价格换
                        ve[q].push_back(pai(j,0));
                    }
                }
                ve[0].push_back(pai(q,p-1));//玻璃球换 so-1
            }
            cin>>m;
            while(m--)
            {
                int a,b,c;
                cin>>a>>b>>c;
                ve[a].push_back(pai(b,c));
            }
            dij();
            int dd[30];
            for(i=1;i<=n;i++)
            {
                cout<<i<<" "<<dis[i]<<endl;
                dd[i]=dis[i];
            }
            int k,sum=0;
            for(i=1;i<=n;i++)//这里要注意 是每个商品看过去 (看是否由其他两个相加可以得到他 可以的话+1
                                 //但是 要是他可以由这两个商品相加得到  又可以由那两个商品相加得到  那只能算一次
            {
                bool bf=false;
                for(j=1;j<n;j++)
                {
                    for(k=j+1;k<=n;k++)
                    {
                        if(dd[i]==dd[j]+dd[k]&&i!=k&&i!=j&&bf==false)
                        {
                            sum++;
                            bf=true;
                            break;
                        }
                    }
                    if(bf)break;
                }
            }
         /*   map<int,int>mp;/
            mp.clear();
            sort(dd+1,dd+n+1);
            for(i=1;i<=n;i++)
            {
                for(j=i+1;j<=n;j++)
                {
                    for(k=j+1;k<=n;k++)//这个是错的 因为k没有从1开始
                    {
                        if(dd[i]+dd[j]==dd[k])
                        {
                            if(mp[dd[k]]==0)sum++,mp[dd[k]]=1;
                        }
                    }
                }
            }*/
            cout<<sum<<endl;
        }
    }
  • 相关阅读:
    HDU4411 最小费用流
    HDU5934 强连通分量
    一个问题
    SAP模板
    KMP模板
    ]C#中执行SQL文件脚本的代码(非常有用)
    C#调用非托管程序5种方式
    [转]C#中的静态常量(const)和动态常量(static和readonly)用法和区别
    [转]C#开发命名规范总结整理
    [转]关于同步方法里面调用异步方法的探究
  • 原文地址:https://www.cnblogs.com/ydw--/p/11337809.html
Copyright © 2011-2022 走看看