P1339 [USACO09OCT]熱浪Heat Wave
阿新 • • 發佈:2018-12-01
典型的最短路問題
獻上樸素Dijsktra、SPFA解法(其實不用去重邊,洛谷的資料沒那麼坑)
1.Dijkstra解法
#include <cstdio> #include <vector> using namespace std; int dist[2510]; struct Node{ int num; bool know; int path; vector <int> adj; }g[2510]; int w[2510][2510]; //記錄邊權 const int INF=10000; void Dijkstra(int ts,int te,int n) { for (int i=1;i<=n+1;i++) { dist[i]=INF; g[i].know=false; g[i].path=0; } dist[ts]=0; vector <int> :: iterator it; for ( ; ; ) { int v=n+1; /* 不斷從當前未知頂點中選取距離源點最近的點,進行更新 */ for (int i=1;i<=n;i++) { if (g[i].know==false && dist[i] < dist[v] ) { v=i; } } if (v==n+1) break; g[v].know=true; for (it=g[v].adj.begin();it!=g[v].adj.end();it++) { if (dist[*it] > dist[v]+w[v][*it]) { dist[*it]=dist[v]+w[v][*it]; g[*it].path=v; } } } int ans=dist[te]; printf ("%d\n",ans); } int main() { int n,m,ts,te,rs,re,ci; scanf ("%d%d%d%d",&n,&m,&ts,&te); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) w[i][j]=INF; for (int i=1;i<=m;i++) { scanf ("%d%d%d",&rs,&re,&ci); g[re].adj.push_back(rs); g[rs].adj.push_back(re); w[re][rs]=ci; w[rs][re]=ci; } Dijkstra (ts,te,n); return 0; }
2.SPFA解法(map存權值比二維陣列好很多)
#include <cstdio> #include <queue> #include <map> using namespace std; const int INF=1<<29; struct Node{ vector <int> adj; }g[2510]; map <int,int> mp[2510]; void SPFA(int n,int ts,int te) { int dis[2510]; int vis[2510]; for (int i=1;i<=n;i++) { dis[i]=INF; vis[i]=0; } queue <int> q; q.push(ts); dis[ts]=0; vis[ts]=1; vector <int> :: iterator it; while (!q.empty()) { int v=q.front(); vis[v]=0; q.pop(); for (it=g[v].adj.begin();it!=g[v].adj.end();it++) { if (dis[*it] > dis[v] + mp[v][*it]) { dis[*it] = dis[v] + mp[v][*it]; if (vis[*it]==0) { q.push(*it); vis[*it]=1; } } } } printf ("%d\n",dis[te]); } int main() { int t,c,ts,te; int rs,re,ci; scanf ("%d%d%d%d",&t,&c,&ts,&te); for (int i=0;i<c;i++) { scanf ("%d%d%d",&rs,&re,&ci); if (mp[re][rs]==0)//去重邊 { g[re].adj.push_back(rs); g[rs].adj.push_back(re); mp[re][rs]=mp[rs][re]=ci; } else if (ci<mp[re][rs]) { mp[re][rs]=mp[rs][re]=ci; } } SPFA(t,ts,te); return 0; }