枚举+最短路
题意是说出发地 和 目的地 之间有一条边是免费的。问你最小费用。
误区:求出最短路-路径中的最大边。(有些其他边免费之后,可能最短路就变了)
正确思路:枚举每条边,将其费用设为0.然后求最短路。找费用最小。
这是无向图,至于地名可以用map映射。
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x7fffffff #define eps 1e-6 #define LL long long using namespace std; int n,m; map<string,int>city; struct lx { int v,len; }; vector<lx>g[501]; int x,y,ans; struct edge { int u,v; }; void SPFA(edge flag) { queue<int>q; bool vis[501]; int dis[501]; for(int i=0; i<501; i++) dis[i]=INF,vis[i]=0; dis[x]=0; vis[x]=1; q.push(x); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int j=0; j<g[u].size(); j++) { int v=g[u][j].v; int len=g[u][j].len; if((u==flag.u&&v==flag.v)||(u==flag.v&&v==flag.u)) { len=0; } if(dis[v]>dis[u]+len) { dis[v]=dis[u]+len; if(!vis[v]) { vis[v]=1; q.push(v); } } } } ans=min(ans,dis[y]); } int main() { char a[11],b[11]; while(scanf("%s%s",a,b)!=EOF) { city.clear(); for(int i=0; i<501; i++) g[i].clear(); int u,v,len,cot=1; x=city[a]; if(x==0) { city[a]=cot++; x=cot-1; } y=city[b]; if(y==0) { city[b]=cot++; y=cot-1; } scanf("%d",&m); queue<edge>que; for(int i=0; i<m; i++) { scanf("%s%s%d",a,b,&len); u=city[a]; if(u==0) { city[a]=cot++; u=cot-1; } v=city[b]; if(v==0) { city[b]=cot++; v=cot-1; } lx now; now.len=len; now.v=v,g[u].push_back(now); now.v=u,g[v].push_back(now); edge tmp; tmp.u=u,tmp.v=v; que.push(tmp); } ans=INF; while(!que.empty()) { edge tmp=que.front();que.pop(); SPFA(tmp); } printf("%d\n",ans); } }
原文地址:http://blog.csdn.net/dongshimou/article/details/37968655