链接:http://poj.org/problem?id=1062
具有点权限制的最短路,在松弛度内枚举区间限制跑最短路就好。
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 510
#define MAXM 10007
int n,m;
struct node
{
int v,next;
int val;
} edge[MAXM];
int head[MAXN],ind;
void add_edge(int u, int v, int val)
{
edge[ind].v=v;
edge[ind].val=val;
edge[ind].next=head[u];
head[u]=ind++;
}
int cnt[MAXN],vis[MAXN];
int lv[MAXN];
int dis[MAXN];
int top,ans;
bool SPFA(int S)
{
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
//memset(dis,0,sizeof(0));
for(int i=0; i<=n; ++i)
dis[i]=INF;
vis[S]=1;
dis[S]=0;
queue<int>que;
que.push(S);
cnt[S]++;
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=0;
for(int i=head[u]; i+1; i=edge[i].next)
{
int v=edge[i].v;
if(dis[v]>dis[u]+edge[i].val && lv[v]<=top && lv[v]>=top-m)
{
dis[v]=dis[u]+edge[i].val;
if(!vis[v])
{
vis[v]=1;
que.push(v);
// if(++cnt[v]>n)return 0;
}
}
}
}
// cout<<dis[0]<<endl;
ans=min(ans,dis[0]);
return 1;
}
int main()
{
int T;
// cin>>T;
while(scanf("%d%d",&m,&n)!=EOF)
{
ind=0;
memset(head,-1,sizeof(head));
int x,y,a,b,c;
// scanf("%d%d",&m,&n);
int VAL,PP;
for(a=1; a<=n; ++a)
{
int val,p,k;
scanf("%d%d%d",&val,&p,&k);
lv[a]=p;
if(a==1)PP=p;
if(PP-p<=m)
add_edge(a,0,val);
for(int j=0; j<k; ++j)
{
int v;
scanf("%d%d",&b,&v);
add_edge(a,b,v);
}
}
lv[0]=PP;
ans=INF;
for(top=PP; top<=PP+m; ++top)
SPFA(1);
cout<<ans<<endl;
}
return 0;
}
/*
2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8
*/