BZOJ-1614 [Usaco2007 Jan]Telephone Lines架设电话线(SPFA+有后效性的dp)
题目描述
在 \(n(1\leq n\leq 1000)\) 个点,\(m(1\leq m\leq 10000)\) 条边的无向图上求出一条从点 \(1\) 到点 \(n\) 的路径,使路径上第 \(k+1\) 大的边权尽量小。
分析
设 \(dp[x][j]\) 为从点 \(1\) 到点 \(x\),途中已经指定了 \(j\) 条边免费时,经过的路径上最大边权的最小值(即选择一条从 \(1\) 到 \(x\) 的路径,使路径上第 \(j+1\) 大的边权尽量小)。如果有一条从点 \(x\) 到点 \(y\) 长度为 \(z\) 的无向边,则应该用 \(\max(dp[x][j],z)\) 更新 \(dp[y][j]\) 的最小值,表示不在边 \((x,y,z)\) 上使用免费服务;然后用 \(dp[x][j]\) 更新 \(dp[y][j+1]\) 的最小值,表示在边 \((x,y,z)\) 上使用免费服务。
动态规划对状态空间的遍历构成一张有向无环图,遍历顺序就是该有向无环图的一个拓扑序。有向无环图中的节点对应问题中的"状态",图中的边则对应状态之间的"转移",转移的选取就是动态规划中的"决策"。
刚才设计的状态转移显然是有后效性的。在有后效性时,一种解决方案就是利用迭代思想,借助 \(\text{SPFA}\) 算法进行动态规划,直至所有状态收敛(不能再更新)。
从最短路的角度去理解,图中的节点也不仅限于 "整数编号",可以扩展到二维,用二元组 \((x,j)\) 代表一个节点,从 \((x,j)\) 到 \((y,j)\) 有长度为 \(z\) 的边,从 \((x,j)\) 到 \((y,j+1)\) 有长度为 \(0\) 的边。$dp[x][j] $ 表示从起点 \((1,0)\) 到节点 \((x,j)\),路径上最长的边最短是多少,这是 \(n\times m\) 个点,\(j\times m\) 条边的广义单源最短路问题,使用 \(\text{SPFA}\) 算法,对于非特殊构造的数据,时间复杂度为 \(O(knm)\),其中 \(k\) 为一个随机常数。
代码
#include<cstring>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1010,M=10010,INF=0x3f3f3f3f;
int n,m,k;
int head[N*N],dist[N*N],num_edge;
bool vis[N*N];
queue<int> Q;
struct Edge
{
int to;
int dis;
int Next;
}edge[N*M];
void add_edge(int from,int to,int dis)
{
edge[++num_edge].to=to;
edge[num_edge].dis=dis;
edge[num_edge].Next=head[from];
head[from]=num_edge;
}
void SPFA()
{
memset(dist,0x3f,sizeof(dist));
dist[1]=0;
vis[1]=1;
Q.push(1);
while(!Q.empty())
{
int x=Q.front();
Q.pop();
vis[x]=0;
for(int i=head[x];i;i=edge[i].Next)
{
int y=edge[i].to,z=edge[i].dis;
if(dist[y]>max(dist[x],z))
{
dist[y]=max(dist[x],z);
if(!vis[y])
{
Q.push(y);
vis[y]=1;
}
}
}
}
}
int main()
{
cin>>n>>m>>k;
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
for(int j=0;j<=k;j++)
{
add_edge(x+j*n,y+j*n,z);
add_edge(y+j*n,x+j*n,z);
}
for(int j=0;j<=k-1;j++)
{
add_edge(x+j*n,y+(j+1)*n,0);
add_edge(y+j*n,x+(j+1)*n,0);
}
}
SPFA();
if(dist[(k+1)*n]==INF)
puts("-1");
else
cout<<dist[(k+1)*n]<<endl;
return 0;
}
posted on 2020-11-09 22:35 DestinHistoire 阅读(103) 评论(0) 收藏 举报
浙公网安备 33010602011771号