FJUT 3930最短パス

moxinとダブルチーズが破産ので、映画を見に上記の郭moxinといえば絶望のmoxin我々は唯一の野菜を販売するビジネスを開始することができます

もちろん、あなたが購入野菜を持っているので、moxinが、ここで比較の店は素晴らしい、購入に行って、次のルールを守ってください。

1つの異なる野菜が同じ値を有する場合、その後、野菜は野菜を栽培することができ、値がB野菜を野菜を栽培値に等しい(例えば、交換することができ、B入れ替えは、交換機に必要とされません)余分な値を過ごします

2.野菜の皿の別の種類の値で人民元交換の+ X値を交渉することができ

3.直接使用することができる皿の購入、食品の種類に元の値に等しいです

質問があるので、moxinはすべての購入を知りたい野菜の最小、どのくらいの人民元が必要ですか?

入力
最初の入力線T(1 <= T <= 10)、 T基の代表

第2の行入力N、M(2 <= N <= 1E3、0 <= M <= 1E3)

交渉の代表的な野菜の関係は、N、M種類

次のn行、各ラインは二つの整数、B(1 <= A <= N、1 <= B <= 1E5)を有しています

Nは、Bの値に野菜を栽培、野菜を表し、

その後各行は三つの整数、B、C(1 <= A <= N、1 <= B <= N、1 <= C <= 1E5、!= B)を有し、行のm個

野菜の代表人民元の為替bの+ C値は、野菜を栽培することができます

(データは、合計7に設定しました)

出力
のn行

ラインあたりの整数であり、iが各行が最小コストに対応する所望の野菜の整数を表します。

SampleInput
1
3 1
1 7
2 2
3 2
1 3 1
SampleOutput
7
2
2

質問の意味:、あまり特定の皿の価値を作り、すべての食品の最小コスト得ようするには、3つの方法で得ることができる
より、良い思考最短経路問題とし、各マップの野菜との関係は、答えを得るdijstraビルドを実行します。アイデアをコメントを参照するコードの具体的な構成を示すことの困難の嘘
、私は私の服をこすり暴力フロイドの手のスコープで見ていないのとでは大きなTLEを発表しました

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdio>

using namespace std;
typedef pair<int,int> p;

const int maxn=1e3+5;
const int inf=0x3f3f3f3f;
int n,m;

struct edge
{
    int to;
    int cost;
    edge(int tt,int cc):to(tt),cost(cc){}
};

int dist[maxn];
int vis[maxn];

vector<edge>g[maxn];


void dj(int s)///di就不多说了 套板子就行
{
    fill(dist,dist+n+1,inf);
    priority_queue<p,vector<p>,greater<p> >que;

    dist[s]=0;
    que.push(p(0,s));

    while(!que.empty())
    {
        p now=que.top();
        que.pop();

        int temp=now.second;

        if(now.first>dist[temp])
            continue;

        for(int i=0; i<g[temp].size(); i++)
        {
            edge next=g[temp][i];

            if(dist[next.to]>dist[temp]+next.cost)
            {
                dist[next.to]=dist[temp]+(int)next.cost;

                que.push(p(dist[next.to],next.to));
            }
        }
    }
}


int main()
{
    int t;

    scanf("%d",&t);

    while(t--)
    {
        scanf("%d%d",&n,&m);
        memset(vis,0,sizeof(vis));///初始化

        for(int i=0; i<=n; ++i)
            g[i].clear();


        int a,b,c;

        for(int i=0; i<n; ++i)
        {
            scanf("%d%d",&a,&b);
            vis[a]=b;
            g[0].push_back(edge(a,b));///a种菜的价值为b
        }

        for(int i=0; i<m; ++i)
        {
            scanf("%d%d%d",&a,&b,&c);
            g[a].push_back(edge(b,c));///可以通过a种菜的花费c元得到b种菜
        }

        for(int i=1; i<=maxn; ++i)
        {
            for(int j=1; j<=maxn; ++j)
            {
                if(vis[i]!=0 && i!=j &&vis[i]==vis[j])///不同的菜有相同的价值是可以互换,那就在相同价值的a,b两种菜之间建立一条权值为0的边
                {
                    g[i].push_back(edge(j,0));
                    g[j].push_back(edge(i,0));
                }
            }
        }

        dj(0);

        for(int i=1; i<maxn; ++i)///输出即可
        {
            if(vis[i])
                printf("%d\n",dist[i]);
        }
    }
    return 0;
}
公開された54元の記事 ウォンの賞賛0 ビュー1219

おすすめ

転載: blog.csdn.net/weixin_44144278/article/details/100025553
おすすめ