题目链接:
http://poj.org/problem?id=1062
题解:
枚举每一个可以交换的区间进行dijkstra,寻找源点到其他所有点的距离的最小值
AC代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define INF 1e8;
using namespace std;
const int maxn = 200;
int dis[maxn],g[maxn][maxn],m,n;
bool v[maxn];
int sb[200][2];
int maxb,minn;
void dijkstra(int bg,int ed)
{
minn = INF;maxb = 0;
for(int i = 1; i <= n; i++)dis[i] = INF;
dis[1] = 0;
memset(v,0,sizeof(v));
for(int i = 1; i <= n;i++)
{
int mark = -1,mindis = INF;
for(int j = 1; j <= n; j++)
{
if(!v[j] && dis[j] < mindis)
{
mindis = dis[j];
mark = j;
}
}
v[mark] = 1;
for(int j = 1; j <= n; j++) if(!v[j] && sb[j][1] >= bg && sb[j][1] <= ed)
dis[j] = min(dis[j],dis[mark] + g[mark][j]);
}
}
int main()
{
while(~scanf("%d %d", &m, &n))
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
g[i][j] = INF;
}
}
for(int i = 1; i <= n; i++)
{
int k,b,c;
scanf("%d%d%d",&sb[i][0],&sb[i][1],&k);
for(int j = 1; j <= k; j++)
{
scanf("%d%d",&b,&c);
if(c < g[i][b])
g[i][b]= c;
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(abs(sb[i][1]-sb[j][1]) > m)g[i][j] = INF;
}
}
int ans = 10000;
for(int i = sb[1][1]-m; i <=sb[1][1]; i++)
{
dijkstra(i,i+m);
for(int i = 1; i <= n; i++)
{
if(abs(sb[i][1] - sb[1][1]) > m)continue;
ans = min(ans,dis[i] + sb[i][0]);
}
}
printf("%d\n",ans);
}
return 0;
}