100269D(最短路 spfa,邊權不固定的最短路 )
阿新 • • 發佈:2019-02-14
這是一個很好的 最短路的問題 。 很好。
題意: 給你n 個商品 m 中換法 a,b,c a可以用 b 或者c 來換 當然 也可以花錢買。 問你 想要得到1的最小花費。
思路: 其實如果抽象一下 就是一個 邊權 可以改變的最短路問題。 既然 c 和 b 可以換來a 那麼如果我們知道 c和b 的花費
比 a 的花費小的話 , 那麼我們就可以 用b 和 c 來鬆弛 a 那麼就相當於 從 c 建一條 邊權為b的花費 的路 走到a ,也相當於 從b 建一條 c的花費的 路到a , 那麼再想 如果 a 被 鬆弛過了 ,那麼他是否也可以去鬆弛別的點呢。 答案是肯定的。 所以我們這裡就可以用 spfa 去不斷地鬆弛每一點。
程式碼:
#include<stdio.h> #include<string.h> #include<queue> #include<iostream> #include<algorithm> #define M 100005 #define N 10005 using namespace std; typedef long long ll; const ll inf=1e18+5; struct node { int u,v; }; int cnt; int head[N]; vector< node >ve[N]; int vis[N];//,dis[N]; int n,m; ll c[N]; /* void add(int u,int v1,int v2) { edge[++cnt].v1=v1; edge[cnt].v2=v2; edge[cnt].next=head[u]; head[u]=cnt; return ; }*/ void spfa() { queue< int >q; int u,v1,v2; for(int i=1;i<=n;i++) { q.push(i); vis[i]=1; } while(!q.empty()) { u=q.front(); q.pop(); vis[u]=0; //printf("u: %d \n",u); int sz=ve[u].size(); for(int i=0;i<sz;i++) { int v=ve[u][i].v; int w=c[ve[u][i].u]; if(c[v]>c[u]+w) { c[v]=c[u]+w; if(vis[v]==0) { vis[v]=1; q.push(v); } } } } return ; } int main() { freopen("dwarf.in","r",stdin); freopen("dwarf.out","w",stdout); cin>>n>>m; int u,v1,v2; cnt=0; memset(head,-1,sizeof(head)); //memset(dis,inf ,sizeof(dis)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) cin>>c[i]; node tmp; for(int i=1;i<=m;i++) { cin>>u>>v1>>v2; tmp.u=v1; tmp.v=u; ve[v2].push_back(tmp); tmp.u=v2; ve[v1].push_back(tmp); //ve.push_back(u); //add(u,v1,v2); } spfa(); printf("%lld\n",c[1]); return 0; }