題目描述:
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
數據範圍:
1≤n,m≤103,1≤S,T,a,b≤n,0≤k≤m,1≤l≤106.
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; }