upc / Luogu p1875-Jiajiaの魔法のポーション(最短経路+グラフ理論モデル変換)

本旨:

薬液のボトルの場合、シロップの重量はp [i]あたりで、2つの方法で新しい薬を入手します
。1。後でシロップCを指示します。2。A
+ B = Cなどの2つのシロップを合成
して、シロップに最小0を与えます。コストとオプションの数

回答:

この問題の解決策の数は、最短経路数と同様に考えることができるため、グラフモデルに変換する必要があります
。dist[i]が合成ポーションiの最低コストを表す場合、最低コストを更新する方法dist [j]。
従来の最短経路最短経路が決定されたポイントから開始し、u-> vを使用してvをuで更新します。問題は、2つのポーションが1つのポーションを合成することです。
次に、2つのポイントから開始します。最短パスが決定されました。A+ B合成Cの
場合dist [c]> dist [A] + dist [B]を使用して更新し
ます。ソリューションの数は、最短パス数のテンプレートです。

A + A = Cの場合は穴があり、画像を保存するときに必要なエッジは1つだけです(18ポイントと100ポイントの差)

コード

int n,head[maxn],cnt,dist[maxn],vis[maxn],link[1600][1600],ans[maxn];
struct node {
    
    
    int u,v,w,next;
} e[maxn];
void add(int u,int v) {
    
    
    e[cnt].u=u,e[cnt].v=v;
    e[cnt].next=head[u],head[u]=cnt++;
}
void slove() {
    
    
    priority_queue<PII,vector<PII>,greater<PII> > q;
    rep(i,1,n) q.push({
    
    dist[i],i});
    while(q.size()) {
    
    
        PII fr= q.top();
        q.pop();
        int dian=fr.second;
        int dis=fr.first;
        if(vis[dian]) continue;
        vis[dian]=1;
        for(int i= head[dian]; ~i; i=e[i].next) {
    
    
            int v=e[i].v;
            int w = link[dian][v];
            if(vis[v]==0) continue;
            if(dist[w]>dis+dist[v]) {
    
    
                dist[w]=dis+dist[v];
                ans[w] = ans[v]*ans[dian];
                q.push({
    
    dist[w],w});
            } else if(dist[w]==dis+dist[v]) {
    
    
                ans[w]+=ans[v]*ans[dian];
            }
        }
    }
}
int  main() {
    
    
    n=read(),mst(head,-1);
    rep(i,1,n) dist[i]=read(),ans[i]=1;
    int u,v,w;
    while(cin>>u>>v>>w) {
    
    
        u++,v++,w++;
        add(u,v);
       if(u==v) continue;
        add(v,u);
        link[v][u]=w,link[u][v]=w;
    }
    slove();
    printf("%d %d",dist[1],ans[1]);
    return 0;

}

おすすめ

転載: blog.csdn.net/wmy0536/article/details/109702091