解题报告:
由于顶点(城镇)的数目只有200个,所以可以采用邻接矩阵的形式来存储,代码会更简洁些,也不容易出错。但是处于练习的目的,采用邻接表+优先队列的方式实现,优先队列使用STL中的priority_queue。很基础的单源单汇最短路径。
解题报告:
基本和1874是一样的,只是数据量小了,并且要求当n==0 && m==0时终止,值得注意!这道题同时也保证了一定是可达的,所以输出时可以直接输出。
解题报告:
这是一道多源多汇的最短路径问题,要新增一个统一的虚源,记为0(其实就是看成是草儿的家),并且0和其它源的距离都是0,这样就完成了转化。值得注意的是,输入数据是有重边的,如果用邻接矩阵做,要比较去重,邻接表的话,直接做就是了!
解题报告:
看完题目直接笑喷了,能不要这么逗么!!!其实这题也就是要处理下字符串而已,直接用map映射成整数,映射完后,就跟2544和1874是一样的了。唯一值得注意的就是:start和end是可能一样的!
/// HDU 1874 邻接表+优先队列 #include<iostream> #include<vector> #include<queue> #include<utility> #include<climits> using namespace std; typedef pair<int,int> mp; int n,m; // n towns and m roads int S,T; //Source and Terminate const int maxv=1000+10; bool vis[maxv]; int dist[maxv]; // dist[i]表示S到i的最短距离 int parent[maxv]; // parent[i]表示S到i的最短路径中i的前一个节点 vector<mp> V[maxv]; //邻接表[i:j1,j2...]和权重w void dijkstra(int S) { //initial for(int i=0;i<maxv;++i) {dist[i]=INT_MAX;vis[i]=false;} priority_queue<mp,vector<mp>,greater<mp> > heap; dist[S]=0; heap.push(mp(0,S)); while( !heap.empty() ) { //initial mp now=heap.top(); heap.pop();//pop掉的是当前所有备选顶点中距离S最近的点 int u=now.second;//int uCost=now.first; if(vis[u]) continue; vis[u]=true; for(int i=0;i<V[u].size();++i) { int v=V[u][i].second; int edgeCost=V[u][i].first; if(dist[u]+edgeCost < dist[v]){ dist[v]=dist[u]+edgeCost ; parent[v]=u; heap.push(mp(dist[v],v)); } } //for } } void printPath(int TT) { if(parent[TT]==S) cout<<S<<"->"<<TT; else{ printPath(parent[TT]); cout<<"->"<<TT; } } int main() { int v1,v2,w,ans; while(cin>>n>>m) { for(int i=0;i<n;++i) V[i].clear(); for(int i=0;i<m;++i) { cin>>v1>>v2>>w; V[v1].push_back(mp(w,v2)); V[v2].push_back(mp(w,v1)); } cin>>S>>T; dijkstra(S); ans=(dist[T]==INT_MAX?-1:dist[T]); cout<<ans<<endl; } }
// HDU 2544 (邻接表+ 优先队列) #include<iostream> #include<vector> #include<queue> #include<utility> #include<climits> using namespace std; typedef pair<int,int> mp; struct edge{ int next,cost; edge(){} edge(int n,int c):next(n),cost(c){} }; int n,m; // n towns and m roads int S,T; //Source and Terminate const int maxv=1000+1; int dist[maxv]; // dist[i]表示S到i的最短距离 int previous[maxv]; // prev[i]表示S到i的最短路径中i的前一个节点 vector<edge> V[maxv]; //邻接表[i:j1,j2...]和权重w int dijkstra(int S,int T) { //initial for(int i=1;i<=n;++i) dist[i]=INT_MAX; dist[S]=0; priority_queue<mp> heap; heap.push(mp(dist[S],S)); while( !heap.empty() ) { mp now=heap.top(); heap.pop();//pop掉的是当前所有备选顶点中距离S最近的点 int nowV=now.second;int nowCost=now.first; //if(nowV==T) return dist[T]; if(nowV!=S && dist[nowV]<= nowCost) continue;//由于顶点的值会更新,旧的会形成冗余 // dist[nowV]是已经确定了的最小距离,nowCost是当前路径下nowV的距离 for(int i=0;i<V[nowV].size();++i) { int nextV=V[nowV][i].next; int edgeCost=V[nowV][i].cost; if(nowCost+edgeCost < dist[nextV]){ dist[nextV]=nowCost+edgeCost ; previous[nextV]=nowV; heap.push(mp(dist[nextV],nextV)); } } //for } return dist[T]; } int main() { int v1,v2,w; while(cin>>n>>m && n+m) { for(int i=1;i<=n;++i) V[i].clear(); for(int i=1;i<=m;++i) { cin>>v1>>v2>>w; V[v1].push_back(edge(v2,w)); V[v2].push_back(edge(v1,w)); } cout<<dijkstra(1,n)<<endl; } }
/// HDU 2066 (邻接矩阵+优先队列) #include<iostream> #include<vector> #include<queue> #include<utility> #include<climits> using namespace std; //why scanf is better than cin??? typedef pair<int,int> mp; int S,T; //Source and Terminate const int maxv=1000+50; bool vis[maxv]; int dist[maxv]; // dist[i]表示S到i的最短距离 int parent[maxv]; // parent[i]表示S到i的最短路径中i的前一个节点 int mat[maxv][maxv]; //邻接矩阵 void dijkstra(int source) { initial for(int i=0;i<maxv;++i) {dist[i]=INT_MAX; vis[i]=false;} priority_queue<mp,vector<mp>,greater<mp> > heap; dist[source]=0; heap.push(mp(dist[source],source)); while( !heap.empty() ) { mp now=heap.top(); heap.pop();//pop掉的是当前所有备选顶点中距离S最近的点 int u=now.second; if(vis[u]) continue; //可能重复push同一个u vis[u]=true; for(int v=1;v<maxv;++v) if(!vis[v] && mat[u][v]!=INT_MAX && dist[u]+mat[u][v] < dist[v]) { // relax松弛 dist[v]=dist[u]+mat[u][v] ; parent[v]=u; heap.push(mp(dist[v],v)); } } } void printPath(int TT) { if(parent[TT]==S) cout<<S<<"->"<<TT; else{ printPath(parent[TT]); cout<<"->"<<TT; } } int main() { int v1,v2,w; int t,s,d,end[maxv]; //t条路径(可重复),d个起点,t个终点 while(cin>>t>>s>>d) { 初始化邻接矩阵 for(int i=0;i<maxv;++i) for(int j=i;j<maxv;++j) mat[i][j]=mat[j][i]=INT_MAX; 输入 for(int i=1;i<=t;++i){ cin>>v1>>v2>>w; if(mat[v1][v2]>w)//去重 mat[v1][v2]=mat[v2][v1]=w; } for(int i=1;i<=s;++i){ cin>>v2; mat[0][v2]=0; // 多起点,设置统一起点0 } for(int i=0;i<d;++i) cin>>end[i]; // 多终点 dijkstra dijkstra(0); int ans=INT_MAX; for(int i=0;i<d;++i){ printPath(end[i]);cout<<endl; if(dist[end[i]]<ans) ans=dist[end[i]]; } //输出最近终点的距离 cout<<ans<<endl; } }
/// HDU 2066 (邻接表+优先队列) #include<iostream> #include<vector> #include<queue> #include<utility> #include<climits> using namespace std; typedef pair<int,int> mp; int n,m; // n towns and m roads int S,T; //Source and Terminate const int maxv=1000+10; bool vis[maxv]; int dist[maxv]; // dist[i]表示S到i的最短距离 int parent[maxv]; // parent[i]表示S到i的最短路径中i的前一个节点 vector<mp> V[maxv]; //邻接表[i:j1,j2...]和权重w void dijkstra(int S) { //initial for(int i=0;i<maxv;++i) {dist[i]=INT_MAX;vis[i]=false;} priority_queue<mp,vector<mp>,greater<mp> > heap; dist[S]=0; heap.push(mp(0,S)); while( !heap.empty() ) { //initial mp now=heap.top(); heap.pop();//pop掉的是当前所有备选顶点中距离S最近的点 int u=now.second; if(vis[u]) continue; vis[u]=true; //if(dist[u]< uCost) continue;//由于顶点的值会更新,旧的会形成冗余 // dist[u]是已经确定了的最小距离,uCost是当前路径下u的距离 for(int i=0;i<V[u].size();++i) { int v=V[u][i].second; int edgeCost=V[u][i].first; if(dist[u]+edgeCost < dist[v]){ dist[v]=dist[u]+edgeCost ; parent[v]=u; heap.push(mp(dist[v],v)); } } //for } } void printPath(int TT) { if(parent[TT]==S) cout<<S<<"->"<<TT; else{ printPath(parent[TT]); cout<<"->"<<TT; } } int main() { int v1,v2,w; int t,s,d,end[maxv]; //t条路径(可重复),d个起点,t个终点 while(cin>>t>>s>>d) { for(int i=0;i<maxv;++i) V[i].clear(); //输入 for(int i=1;i<=t;++i){ cin>>v1>>v2>>w; V[v1].push_back(mp(w,v2)); V[v2].push_back(mp(w,v1)); } for(int i=1;i<=s;++i){ cin>>v2; V[0].push_back(mp(0,v2)); // 多起点,设置统一起点0 } for(int i=0;i<d;++i) cin>>end[i]; // 多终点 dijkstra(0); int ans=INT_MAX; for(int i=0;i<d;++i){ //printPath(end[i]);cout<<endl; if(dist[end[i]]<ans) ans=dist[end[i]]; } //输出最近终点的距离 cout<<ans<<endl; } }
/// HDU 2112 (邻接矩阵+优先队列) #include<iostream> #include<string> #include<map> #include<queue> #include <functional> #include<climits> #include<utility> using namespace std; typedef pair<int,int> pii; const int maxv=150+10; int n,t; string start,finish,s,e; map<string,int> mapp; bool vis[maxv]; int dist[maxv]; //int parent[maxv]; int mat[maxv][maxv]; void dijkstra(int source) { // initial for(int i=0;i<maxv;++i){dist[i]=INT_MAX; vis[i]=false;} priority_queue<pii,vector<pii>,greater<pii> > heap; dist[source]=0;heap.push(pii(dist[source],source)); while( !heap.empty() ) { int u=heap.top().second; heap.pop(); if(vis[u]) continue; vis[u]=true; for(int v=0;v<maxv;++v) if(!vis[v] && mat[u][v]!=INT_MAX && dist[u]+mat[u][v] < dist[v]) { dist[v]=dist[u]+mat[u][v]; //parent[v]=u; heap.push(pii(dist[v],v)); } } } int main() { while(cin>>n && n+1) { cin>>start>>finish; mapp.clear(); for(int i=0;i<maxv;++i)for(int j=i+1;j<maxv;++j) mat[j][i]=mat[i][j]=INT_MAX; int k=0; mapp[start]=k++; mapp[finish]=k++; for(int i=0;i<n;++i){ cin>>s>>e>>t; if(!mapp.count(s)) mapp[s]=k++; if(!mapp.count(e)) mapp[e]=k++; if(t < mat[mapp[s]][mapp[e]]) mat[mapp[e]][mapp[s]]=mat[mapp[s]][mapp[e]]=t; } //if(start==finish){cout<<0<<endl;continue;} //if(n==0){cout<<-1<<endl;continue;} dijkstra(mapp[start]); cout<<(dist[mapp[finish]]==INT_MAX?-1:dist[mapp[finish]])<<endl; } return 0; }
写在最后:
HDU 2680 Choose the best route
HDU 1385
Minimum Transport Cost
时间: 2024-10-14 01:25:48