FJUT 3930 最短路 dijkstra

原题地址:http://www.fjutacm.com/Problem.jsp?pid=3930

本题有三种操作
1.价值一样 可以换菜的品种
2.可以买了a品种菜后在多花x元换b品种
3.直接花钱买菜

求买每种菜的最少价格
仔细想一下 其实就是求单源最短路 也就是dijkstra
那么只要上个模板就好了 问题就在如何建图了
首先菜的品种是1到n 那么我们需要设一个源点 只要不是1到n的范围就好了 这里我们可以选0作为源点
操作1:因为范围1e5 所以我们可以直接把价值相同的菜种记录下来 把两个点连接起来 边权为0 这里需要注意建双向边
操作2:a b c 买了菜种a在加c元可以换菜种b 这个我们建立a到b的单向边 边权为c
操作3:连接源点0和每种菜 边权即为这种菜的直接价格

建图完成后 直接跑个dijkstra即可

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int to,cost;
    node() {}
    node(int to,int cost):to(to),cost(cost) {}
    bool friend operator< (const node &a,const node &b)
    {
        return a.cost>b.cost;
    }
};
vector<node>a[1005];
void dijkstra(int n)
{
    int dis[1005],v[1005]={0};
    memset(dis,0x3f,sizeof dis);
    priority_queue<node>hsy;
    hsy.push(node(0,0));
    while(!hsy.empty())
    {
        node now=hsy.top();
        hsy.pop();
        if(!v[now.to])
        {
            v[now.to]=1;
            dis[now.to]=now.cost;
            for(int i=0; i<a[now.to].size(); i++)
            {
                node next;
                next.to=a[now.to][i].to;
                next.cost=a[now.to][i].cost+now.cost;
                if(!v[next.to])
                    hsy.push(next);
            }
        }
    }
    for(int i=1; i<=n; i++)
        cout<<dis[i]<<endl;
}
int main()
{
    int n,m,t;
    int x,y,d;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(int i=0; i<=1005; i++)
            a[i].clear();
        vector<int> r[100005];
        for(int i=1; i<=n; i++)///连接源点0和每种菜
        {
            scanf("%d%d",&x,&y);
            a[0].push_back(node(x,y));
            r[y].push_back(x);
        }
        for(int i=1; i<=100000; i++)///价格相同的菜 建立边权为0
        {
            int len=r[i].size();
            for(int j=0; j<len; j++)
            {
                for(int k=j+1; k<len; k++)
                {
                    a[r[i][j]].push_back(node(r[i][k],0));
                    a[r[i][k]].push_back(node(r[i][j],0));
                }
             }
        }

        for(int i=1; i<=m; i++)///加价格换菜
        {
            scanf("%d%d%d",&x,&y,&d);
            a[x].push_back(node(y,d));
        }
        dijkstra(n);
    }

}
发布了58 篇原创文章 · 获赞 12 · 访问量 7473

猜你喜欢

转载自blog.csdn.net/qq_43563669/article/details/100024832