生活随笔
收集整理的这篇文章主要介绍了
ZOJ1027 Travelling Fee(DP+SPFA)
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
给一张有向无环图,边都有花费,从某点到某点走的那条路径上的那一条花费最多的边可以省掉,问从起点到终点的最少花费的多少,
往DP想的话,就可以写出这个状态dp[u][mx],表示到达u点已经省掉的花费为mx的最少花费。
用SPFA更新转移方程。。或者理解成队列+我为人人的转移。。其实这题这样子也能解有环图。
看了别人博客,发现还有三种解法:
枚举每一条边作为省掉的边,n次SPFA。这方法简洁,可惜想不出= =跑Dijkstra,根据记录到每一点时的最长边更新,正确性不懂。。Floyd+DP:加个维度,dpk[0\1][u][v],第一维1和0分别表示省和没省最长边的最少花费,dp[1]的转移就是dp[1][u][v]=min(dp[0][u][k]+dp[1][k][v],dp[1][u][k]+dp[0][k][v]),初始dp[1][i][j]=0(<i,j>∈E),好厉害。。 1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 #include<queue>
5 #include<
string>
6 #include<algorithm>
7 using namespace std;
8 #define INF (1<<29)
9 int n,G[
222][
222];
10 int d[
222][
10001];
11 bool vis[
222][
10001];
12 struct Node{
13 int u,mx;
14 Node(
int _u,
int _mx):u(_u),mx(_mx){}
15 };
16 void SPFA(
int vs){
17 for(
int i=
0; i<n; ++
i){
18 for(
int j=
0; j<
10001; ++j) d[i][j]=
INF;
19 }
20 d[vs][
0]=
0;
21 memset(vis,
0,
sizeof(vis));
22 vis[vs][
0]=
1;
23 queue<Node>
que;
24 que.push(Node(vs,
0));
25 while(!
que.empty()){
26 Node nd=
que.front(); que.pop();
27 int u=nd.u,mx=
nd.mx;
28 for(
int v=
0; v<n; ++
v){
29 if(G[u][v]==INF)
continue;
30 if(G[u][v]>mx && d[v][G[u][v]]>d[u][mx]+
mx){
31 d[v][G[u][v]]=d[u][mx]+
mx;
32 if(!
vis[v][G[u][v]]){
33 vis[v][G[u][v]]=
1;
34 que.push(Node(v,G[u][v]));
35 }
36 }
37 if(d[v][mx]>d[u][mx]+
G[u][v]){
38 d[v][mx]=d[u][mx]+
G[u][v];
39 if(!
vis[v][mx]){
40 vis[v][mx]=
1;
41 que.push(Node(v,mx));
42 }
43 }
44 }
45 vis[u][mx]=
0;
46 }
47 }
48 int main(){
49 string name[
222],x[
111],y[
111],vs,vt;
50 int m,z[
111];
51 while(cin>>vs>>
vt){
52 n=
0;
53 scanf(
"%d",&
m);
54 for(
int i=
0; i<m; ++
i){
55 cin>>x[i]>>y[i]>>
z[i];
56 name[n++]=x[i]; name[n++]=
y[i];
57 }
58 sort(name,name+
n);
59 n=unique(name,name+n)-
name;
60 for(
int i=
0; i<n; ++
i){
61 for(
int j=
0; j<n; ++j) G[i][j]=
INF;
62 }
63 for(
int i=
0; i<m; ++
i){
64 int u=lower_bound(name,name+n,x[i])-name,v=lower_bound(name,name+n,y[i])-
name;
65 G[u][v]=
z[i];
66 }
67 SPFA(lower_bound(name,name+n,vs)-
name);
68 int tv=lower_bound(name,name+n,vt)-
name;
69 int res=
INF;
70 for(
int i=
0; i<
10001; ++i) res=
min(res,d[tv][i]);
71 printf(
"%d\n",res);
72 }
73 return 0;
74 }
转载于:https://www.cnblogs.com/WABoss/p/5223179.html
总结
以上是生活随笔为你收集整理的ZOJ1027 Travelling Fee(DP+SPFA)的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。