http://poj.org/problem?id=1062
这个题目有一点点特别,因为数据很小也可以用Floyd跑,但是个人比较钟爱dij。
这个dij是怎么走的呢,首先就是普通的建图,然后就是带上一个地位限制的dij,其他都是一样的。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>
#include <algorithm>
#include <iostream>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e5 + 10;
struct node
{
int to, dist, nxt;
node(int to=0,int dist=0):to(to),dist(dist){}
}exa[maxn];
struct heapnode
{
int u, d;
heapnode(int u=0,int d=0):u(u),d(d){}
bool operator<(const heapnode&a)const
{
return a.d < d;
}
};
int cnt = 0;
int head[maxn];
void add(int u,int v,int w)
{
exa[++cnt] = node(v, w);
exa[cnt].nxt = head[u];
head[u] = cnt;
}
int ans = 0;
int d[maxn], level[maxn], p[maxn];
bool vis[maxn];
int dij(int l,int r)
{
memset(vis, 0, sizeof(vis));
memset(d, inf, sizeof(d));
d[1] = 0;
ans = p[1];
priority_queue<heapnode>que;
que.push(heapnode(1, 0));
while(!que.empty())
{
heapnode x = que.top(); que.pop();
int u = x.u;
if (vis[u]) continue;
vis[u] = true;
for(int i=head[u];i;i=exa[i].nxt)
{
node e = exa[i];
if (level[e.to]<l || level[e.to]>r) continue;
if(d[e.to]>d[u]+e.dist)
{
d[e.to] = d[u] + e.dist;
ans = min(ans, d[e.to] + p[e.to]);
que.push(heapnode(e.to, d[e.to]));
}
}
}
return ans;
}
int main()
{
int m, n;
memset(head, 0, sizeof(head));
scanf("%d%d", &m, &n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d%d%d", &p[i], &level[i], &x);
for(int j=1;j<=x;j++)
{
int a, b;
scanf("%d%d", &a, &b);
add(i, a, b);
}
}
int ex = inf;
for(int l=level[1],r=level[1]+m;r>=level[1];r--,l--)
{
ex=min(ex,dij(l, r));
}
printf("%d
", ex);
return 0;
}