生活随笔
收集整理的這篇文章主要介紹了
ZOJ1027 Travelling Fee(DP+SPFA)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
給一張有向無環(huán)圖,邊都有花費,從某點到某點走的那條路徑上的那一條花費最多的邊可以省掉,問從起點到終點的最少花費的多少,
往DP想的話,就可以寫出這個狀態(tài)dp[u][mx],表示到達u點已經(jīng)省掉的花費為mx的最少花費。
用SPFA更新轉(zhuǎn)移方程。。或者理解成隊列+我為人人的轉(zhuǎn)移。。其實這題這樣子也能解有環(huán)圖。
看了別人博客,發(fā)現(xiàn)還有三種解法:
枚舉每一條邊作為省掉的邊,n次SPFA。這方法簡潔,可惜想不出= =跑Dijkstra,根據(jù)記錄到每一點時的最長邊更新,正確性不懂。。Floyd+DP:加個維度,dpk[0\1][u][v],第一維1和0分別表示省和沒省最長邊的最少花費,dp[1]的轉(zhuǎn)移就是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 }
?
轉(zhuǎn)載于:https://www.cnblogs.com/WABoss/p/5223179.html
總結(jié)
以上是生活随笔為你收集整理的ZOJ1027 Travelling Fee(DP+SPFA)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。