2019牛客暑期多校訓練營(第四場)- J - free

題目描述:

Your are given an undirect connected graph.Every edge has a cost to pass.You should choose a path from S to T and you need to pay for all the edges in your path. However, you can choose at most k edges in the graph and change their costs to zero in the beginning. Please answer the minimal total cost you need to pay.

輸入描述:

The first line contains five integers n,m,S,T,K.

For each of the following m lines, there are three integers a,b,l, meaning there is an edge that costs l between a and b.

n is the number of nodes and m is the number of edges.

輸出描述:

An integer meaning the minimal total cost.

樣例演示:

輸入:

3 2 1 3 1
1 2 1
2 3 2

輸出:

1

數據範圍:

1n,m103,1S,T,a,bn,0km,1l106.
Multiple edges and self loops are allowed.

題目大意:給定一張無向圖,起點爲S,終點爲T,求S-T的最短路,其中可以有k次機會把一條路徑的權值變爲0。

解題思路:分層最短路

AC代碼:

#pragma GCC optimize(3)
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<array>
#include<string>
#include<cstring>
#include<cmath>
#include<cassert>
#include<cstdlib>
#include<utility>
#include<iterator>
using namespace std;
typedef long long ll;
const int maxn  =  1005;
int n,m,s,t,k;
struct  edge
{
    int to,cost;
    edge(){}
    edge(int to,int cost):to(to),cost(cost){}
};
struct  node
{
    int v,w,cnt;
    node(){}
    node(int v,int w,int cnt):v(v),w(w),cnt(cnt){}
    bool operator<(const node&ano)const{return w>ano.w;}
};
int dis[maxn][maxn];
bool vis[maxn][maxn];
vector<edge> G[maxn];
priority_queue<node> pq;
void addG(int u,int v,int w)
{
    G[u].push_back(edge(v,w));
    G[v].push_back(edge(u,w));
}
void dijkstra()
{
    memset(dis,0x3f,sizeof(dis));
    memset(vis,false,sizeof(vis));
    dis[s][0] = 0;
    pq.push(node(s,0,0));
    while(!pq.empty())
    {
        const node top = pq.top();
        pq.pop();
        int u = top.v;
        int nowcnt = top.cnt;
        if(vis[u][nowcnt]==true)continue;
        vis[u][nowcnt] = true;
        for(int i = 0;i<(int)(G[u].size());i++)
        {
            int v = G[u][i].to;
            int w = G[u][i].cost;
            //可以用到免費機會
            if(nowcnt<k&&dis[v][nowcnt+1]>dis[u][nowcnt]&&!vis[v][nowcnt+1])
            {    
                  dis[v][nowcnt+1]=dis[u][nowcnt];
                  pq.push(node(v,dis[v][nowcnt+1],nowcnt+1));
            }
            //不可以用免費機會
            if(dis[v][nowcnt]>dis[u][nowcnt]+w&&!vis[v][nowcnt])
            {
                dis[v][nowcnt]=dis[u][nowcnt]+w;
                pq.push(node(v,dis[v][nowcnt],nowcnt));
            }
        }

    }
}
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);
    cin>>n>>m>>s>>t>>k;
    while(m--)
    {
        int u,v,w;
        cin>>u>>v>>w;
        addG(u,v,w);
    }
    int ans = 0x3f3f3f3f;
    dijkstra();
    for(int i = 0;i<=k;i++)
    {
        ans = min(ans,dis[t][i]);
    }
    cout<<ans<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章