最短路。
先求出一个只包含最短路的$DAG$,然后在$DAG$上$dp$一下就可以了。英文变数字还有$map$转一下。
#include<map> #include<set> #include<ctime> #include<cmath> #include<queue> #include<string> #include<stack> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; int n,m,s,t,num[250]; char tmp[100],A[100],B[100]; map<string,int>xx; map<int,string>yy; vector<int>G[250],nG[250]; int Time[250][250]; int disS[250],disT[250],f[250]; int U[250*250],V[250*250],In[250]; int ss[250],pre[250],sl[250],dp[250]; void spfaS() { memset(f,0,sizeof f); for(int i=1;i<=n;i++) disS[i]=0x7FFFFFFF; queue<int>Q; Q.push(s); f[s]=1; disS[s]=0; while(!Q.empty()) { int h = Q.front(); Q.pop(); f[h]=0; for(int i=0;i<G[h].size();i++) { int to = G[h][i]; if(disS[h]+Time[h][to]<disS[to]) { disS[to] = disS[h]+Time[h][to]; if(f[to]==0) { f[to]=1; Q.push(to); } } } } } void spfaT() { memset(f,0,sizeof f); for(int i=1;i<=n;i++) disT[i]=0x7FFFFFFF; queue<int>Q; Q.push(t); f[t]=1; disT[t]=0; while(!Q.empty()) { int h = Q.front(); Q.pop(); f[h]=0; for(int i=0;i<G[h].size();i++) { int to = G[h][i]; if(disT[h]+Time[h][to]<disT[to]) { disT[to] = disT[h]+Time[h][to]; if(f[to]==0) { f[to]=1; Q.push(to); } } } } } void W() { queue<int>Q; Q.push(s); dp[s]=1; while(!Q.empty()) { int h = Q.front(); Q.pop(); for(int i=0;i<nG[h].size();i++) { int to = nG[h][i]; dp[to]+=dp[h]; if(sl[h]+1>sl[to]) { sl[to] = sl[h]+1; ss[to] = ss[h]+num[to]; pre[to]=h; } else if(sl[h]+1==sl[to]) { if(ss[h]+num[to]>ss[to]) { sl[to] = sl[h]+1; ss[to] = ss[h]+num[to]; pre[to]=h; } } In[to]--; if(In[to]==0) Q.push(to); } } } int main() { scanf("%d%d",&n,&m); scanf("%s%s",A,B); xx[A]=1; yy[1]=A; for(int i=2;i<=n;i++) { scanf("%s",tmp); xx[tmp]=i; yy[i]=tmp; scanf("%d",&num[i]); } s=1; t=xx[B]; for(int i=1;i<=m;i++) { int P; scanf("%s%s",A,B); scanf("%d",&P); int u = xx[A], v = xx[B]; U[i] = u; V[i]=v; Time[u][v]=Time[v][u]=P; G[u].push_back(v); G[v].push_back(u); } spfaS(); spfaT(); for(int i=1;i<=m;i++) { if(disS[U[i]]+disT[V[i]]+Time[U[i]][V[i]]==disS[t]) { nG[U[i]].push_back(V[i]); In[V[i]]++; } if(disS[V[i]]+disT[U[i]]+Time[U[i]][V[i]]==disS[t]) { nG[V[i]].push_back(U[i]); In[U[i]]++; } } W(); vector<int>Ans; stack<int>St; int now=t; while(1) { if(now==0) break; St.push(now); now=pre[now]; } while(!St.empty()) { Ans.push_back(St.top()); St.pop(); } for(int i=0;i<Ans.size();i++) { cout<<yy[Ans[i]]; if(i<Ans.size()-1) printf("->"); else printf(" "); } printf("%d %d %d ",dp[t],disS[t],ss[t]); return 0; }