题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2112
题目意思:中文。。。。 就是就是求最短路,只不过顶点是字符串表示的。
思路:就是用map使字符串达到编号效果,再直接用spfa/dijkstra就行。
太久没用map了,这道题让我捡起来许多,真好!
但被坑了几发,边的范围是1e4,而点为150,我直接用1e4交错了,还以为算法写了,
找了半天,骂自己眼瞎弱鸡。
spfa:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> #include<map> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; map<string,int> m; const int maxn=1e5+10; struct node{ int from,to,next,w; }edge[maxn]; int head[maxn],vis[maxn],d[maxn],cnt,n; queue<int> q; void init()//初始化 { memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(d,0x3f,sizeof(d)); cnt=0; } void add(int u,int v,int w)//前向星连边 { edge[cnt].from=u; edge[cnt].to=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } void spfa(int s)//spfa板子 { d[s]=0; vis[s]=1; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(d[v]>d[u]+edge[i].w) { d[v]=d[u]+edge[i].w; if(!vis[v]) { vis[v]=1; q.push(v); } } } } } int main() { std::ios::sync_with_stdio(false);//cin,cout增加效率的,第一次用。。。。 while(cin>>n&&(n!=-1)) { m.clear();//记得清空map init(); string s1,s2,s,e; int w,num=1; cin>>s>>e; m[s]=num++;//以下都是进map,发现可以当数组用 if(!m[e]) m[e]=num++; for(int i=1;i<=n;i++) { cin>>s1>>s2>>w; if(!m[s1]) m[s1]=num++; if(!m[s2]) m[s2]=num++; add(m[s1],m[s2],w); add(m[s2],m[s1],w); //cout<<m[s1]<<" "<<m[s2]<<" "<<w<<endl; } if(s==e)//顶点相同,加不加都行,spfa都考虑到了 { cout<<0<<endl; continue; } spfa(m[s]); if(d[m[e]]==inf)//没有通路 d[m[e]]=-1; cout<<d[m[e]]<<endl; } return 0; }
dijkstra(优先队列优化,不优化也可以):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> #include<map> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn=1e5+10; map<string,int> m; int n,cnt; struct node{ int from,to,next,val; }edge[maxn]; int head[maxn],vis[maxn],d[maxn]; struct nd{ int id; int dis; bool operator <(const nd &a)const { return dis>a.dis; } }; priority_queue<nd> q;//优先队列 void init()//初始化 { memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(d,0x3f,sizeof(d)); cnt=0; } void add(int u,int v,int w)//前向星连边 { edge[cnt].from=u; edge[cnt].to=v; edge[cnt].val=w; edge[cnt].next=head[u]; head[u]=cnt++; } void dijkstra()//板子 { nd s; s.id=1; s.dis=0; d[1]=0; while(!q.empty()) q.pop(); q.push(s); while(!q.empty()) { s=q.top(); q.pop(); int u=s.id; if(vis[u]) continue; vis[u]=1; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(!vis[v]&&d[v]>d[u]+edge[i].val) { d[v]=d[u]+edge[i].val; nd p; p.id=v;p.dis=d[v]; q.push(p); } } } } int main()//和上面一样 { std::ios::sync_with_stdio(false); while(cin>>n&&(n!=-1)) { m.clear(); init(); string s1,s2,s,e; int w,num=1; cin>>s>>e; m[s]=num++; if(!m[e]) m[e]=num++; for(int i=1;i<=n;i++) { cin>>s1>>s2>>w; if(!m[s1]) m[s1]=num++; if(!m[s2]) m[s2]=num++; add(m[s1],m[s2],w); add(m[s2],m[s1],w); //cout<<m[s1]<<" "<<m[s2]<<" "<<w<<endl; } dijkstra(); if(d[m[e]]==inf) d[m[e]]=-1; cout<<d[m[e]]<<endl; } return 0; }