链接
背景
(USACO) (2009) (Feb) (T3) , (Luogu) (P2939/BZOJ1579)
题意
给定 (n) 个点, (m) 条边的两个端点 (x,y) ,规定一条路径上最多可以使得 (k) 条边变成 (0) 。求 (1) 到 (n) 的最短路径长度。
解法
分层图最短路模板。
由于可以免费 (k) 次,建 (k) 层图(假定变成 (0) 的边数越多图越高)即可。
注意每条边在每一层上连一遍,然后 (x) 向高一层的 (y) 连 (0) 边, (y) 向高一层的 (x) 连 (0) 边。
从 (1) 号点开始 (dijkstra) ,答案是所有层上第 (n) 个点的最短路的最小值。
细节
请务必注意检查图论题的数组开得够不够大。请务必务必务必代入极限数据检验。
代码
$View$ $Code$
```cpp
#include
using namespace std;
inline int read()
{
int ret=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
ret=(ret<<1)+(ret<<3)+ch-'0';
ch=getchar();
}
return ret*f;
}
const int inf=0x3f3f3f3f;
int n,m,k,s,t,u,v,w;
int dis[220005],ans=inf;
int num,head[220005];
bool vis[220005];
struct edge
{
int ver,nxt,w;
}e[4100005];
inline void adde(int u,int v,int w)
{
e[++num].ver=v;
e[num].w=w;
e[num].nxt=head[u];
head[u]=num;
}
void dijkstra(int s)
{
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
priority_queue > q;
dis[s]=0;
q.push(make_pair(0,s));
while(!q.empty())
{
int x=q.top().second;
q.pop();
if(vis[x])
continue;
vis[x]=1;
for(register int i=head[x];i;i=e[i].nxt)
{
int y=e[i].ver,w=e[i].w;
if(dis[x]+w