最短路+DP(个人用的SPFA+完全背包)
做了一上午……开始想用SPFA+BFS。但是写了半天越写越乱,放弃了。
就想到了是不是可以当作背包问题(背出病了……)把鞋子可以使用的次数当作背包容量。做完全背包。
先N次SPFA把 各点的最短距离算出来,其实比较适合Floyd。(个人用vector实现伪邻接表,然后SPFA)
然后SPFA更新路径的时候,当鞋子使用次数不为0的时候,做完全背包。
还有个忧伤的地方就是我把INF=0x7fffffff。结果加上一个数 变成负数了。一直不对。
找了半天,最后加上了 !=INF 才对。
#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 a,b,m,l,k,n; struct lx { int v,len; }; vector<lx>g[101]; int dis[101][101]; void SPFA(int start) { queue<int>q; bool vis[101]; memset(vis,0,sizeof(vis)); q.push(start); vis[start]=1; dis[start][start]=0; 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(dis[start][v]>dis[start][u]+len) { dis[start][v]=dis[start][u]+len; if(v<=a&&!vis[v]) { vis[v]=1; q.push(v); } } } } } void spfa() { bool vis[101]; int dp[101][11]; for(int i=0;i<101;i++) { vis[i]=0; for(int j=0;j<11;j++) dp[i][j]=INF; } queue<int>q; q.push(n); vis[n]=1; dp[n][k]=0; while(!q.empty()) { int u=q.front();q.pop(); vis[u]=0; for(int i=0;i<=k;i++) { for(int j=0;j<g[u].size();j++) { int v=g[u][j].v; int len=g[u][j].len; if(dp[u][i]!=INF&&dp[v][i]>dp[u][i]+len) { dp[v][i]=dp[u][i]+len; if(!vis[v]) { vis[v]=1; q.push(v); } // printf("%d > %d+%d\n",dp[v][i],dp[u][i],len); // dp[u][i]!=INF;注意 } if(i==0)continue; for(v=1;v<=n;v++) { if(v!=u&&dis[u][v]<=l) { if(dp[v][i-1]>dp[u][i]) { dp[v][i-1]=dp[u][i]; if(!vis[v]) { vis[v]=1; q.push(v); } } } } } } } int ans=INF; for(int i=0;i<=k;i++) ans=min(ans,dp[1][i]); printf("%d\n",ans); } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d%d%d%d",&a,&b,&m,&l,&k); for(int i=0;i<101;i++) g[i].clear(); n=a+b; int u,v,len; while(m--) { scanf("%d%d%d",&u,&v,&len); lx now; now.len=len; now.v=v,g[u].push_back(now); now.v=u,g[v].push_back(now); } for(int i=0;i<101;i++) for(int j=0;j<101;j++) dis[i][j]=INF; for(int i=1;i<=n;i++) SPFA(i); spfa(); } }
ZOJ 1232 Adventure of Super Mario
时间: 2024-10-10 16:23:16